"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifyFillRepayment = exports.getRefundInformationFromFill = void 0;
var tslib_1 = require("tslib");
var lodash_1 = tslib_1.__importDefault(require("lodash"));
var assert_1 = tslib_1.__importDefault(require("assert"));
var ethers_1 = require("ethers");
var utils_1 = require("../../../utils");
function getRefundInformationFromFill(relayData, hubPoolClient, bundleEndBlockForMainnet) {
    var chainToSendRefundTo = _getRepaymentChainId(relayData, hubPoolClient, bundleEndBlockForMainnet);
    if (chainToSendRefundTo === relayData.originChainId) {
        return {
            chainToSendRefundTo: chainToSendRefundTo,
            repaymentToken: relayData.inputToken,
        };
    }
    var l1TokenCounterpart = hubPoolClient.getL1TokenForL2TokenAtBlock(relayData.inputToken, relayData.originChainId, bundleEndBlockForMainnet);
    var repaymentToken = hubPoolClient.getL2TokenForL1TokenAtBlock(l1TokenCounterpart, chainToSendRefundTo, bundleEndBlockForMainnet);
    return {
        chainToSendRefundTo: chainToSendRefundTo,
        repaymentToken: repaymentToken,
    };
}
exports.getRefundInformationFromFill = getRefundInformationFromFill;
function verifyFillRepayment(_fill, destinationChainProvider, matchedDeposit, hubPoolClient, bundleEndBlockForMainnet) {
    return tslib_1.__awaiter(this, void 0, void 0, function () {
        var fill, repaymentChainId, fillTransaction, destinationRelayer;
        return tslib_1.__generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    fill = lodash_1.default.cloneDeep(_fill);
                    if ((0, utils_1.isSlowFill)(fill)) {
                        return [2, fill];
                    }
                    repaymentChainId = _getRepaymentChainId(tslib_1.__assign(tslib_1.__assign({}, fill), { fromLiteChain: matchedDeposit.fromLiteChain }), hubPoolClient, bundleEndBlockForMainnet);
                    if (!_repaymentAddressNeedsToBeOverwritten(fill)) return [3, 3];
                    if (!(0, utils_1.chainIsEvm)(fill.destinationChainId)) return [3, 2];
                    (0, assert_1.default)(destinationChainProvider instanceof ethers_1.providers.Provider, "BundleDataClient#verifyFillRepayment: unexpected destination chain provider for chain ID ".concat(fill.destinationChainId));
                    return [4, destinationChainProvider.getTransaction(fill.txnRef)];
                case 1:
                    fillTransaction = _a.sent();
                    destinationRelayer = fillTransaction === null || fillTransaction === void 0 ? void 0 : fillTransaction.from;
                    if (!(0, utils_1.isDefined)(destinationRelayer) || !(0, utils_1.isValidEvmAddress)(destinationRelayer)) {
                        return [2, 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 [2, 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: ".concat(destinationRelayer));
                    return [3, 3];
                case 2: return [2, undefined];
                case 3:
                    fill.repaymentChainId = repaymentChainId;
                    return [2, fill];
            }
        });
    });
}
exports.verifyFillRepayment = verifyFillRepayment;
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;
    }
    var repaymentTokenIsValid = _repaymentChainTokenIsValid(relayData, hubPoolClient, bundleEndBlockForMainnet);
    if (repaymentTokenIsValid) {
        return relayData.repaymentChainId;
    }
    return relayData.originChainId;
}
function _repaymentChainTokenIsValid(relayData, hubPoolClient, bundleEndBlockForMainnet) {
    if (!hubPoolClient.l2TokenHasPoolRebalanceRoute(relayData.inputToken, relayData.originChainId, bundleEndBlockForMainnet)) {
        return false;
    }
    var l1TokenCounterpart = hubPoolClient.getL1TokenForL2TokenAtBlock(relayData.inputToken, relayData.originChainId, bundleEndBlockForMainnet);
    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