"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isSlowFill = isSlowFill;
exports.getSlowFillLeafLpFeePct = getSlowFillLeafLpFeePct;
exports.unpackDepositEvent = unpackDepositEvent;
exports.unpackFillEvent = unpackFillEvent;
exports.getRelayDataHash = getRelayDataHash;
exports.getRelayHashFromEvent = getRelayHashFromEvent;
exports.isUnsafeDepositId = isUnsafeDepositId;
exports.getMessageHash = getMessageHash;
exports.findInvalidFills = findInvalidFills;
var tslib_1 = require("tslib");
var viem_1 = require("viem");
var common_1 = require("./common");
var constants_1 = require("../constants");
var interfaces_1 = require("../interfaces");
var arch_1 = require("../arch");
var BigNumberUtils_1 = require("./BigNumberUtils");
var DepositUtils_1 = require("./DepositUtils");
var NetworkUtils_1 = require("./NetworkUtils");
var AddressUtils_1 = require("./AddressUtils");
function isSlowFill(fill) {
    return fill.relayExecutionInfo.fillType === interfaces_1.FillType.SlowFill;
}
function getSlowFillLeafLpFeePct(leaf) {
    var relayData = leaf.relayData, updatedOutputAmount = leaf.updatedOutputAmount;
    return relayData.inputAmount.sub(updatedOutputAmount).mul(common_1.fixedPointAdjustment).div(relayData.inputAmount);
}
function unpackDepositEvent(rawEvent, originChainId) {
    var event = rawEvent;
    return tslib_1.__assign(tslib_1.__assign({}, event), { originChainId: originChainId, depositor: (0, AddressUtils_1.toAddressType)(event.depositor, originChainId), recipient: (0, AddressUtils_1.toAddressType)(event.recipient, event.destinationChainId), inputToken: (0, AddressUtils_1.toAddressType)(event.inputToken, originChainId), outputToken: (0, AddressUtils_1.toAddressType)(event.outputToken, event.destinationChainId), exclusiveRelayer: (0, AddressUtils_1.toAddressType)(event.exclusiveRelayer, event.destinationChainId), messageHash: getMessageHash(event.message) });
}
function unpackFillEvent(rawEvent, destinationChainId) {
    var event = rawEvent;
    return tslib_1.__assign(tslib_1.__assign({}, event), { destinationChainId: destinationChainId, depositor: (0, AddressUtils_1.toAddressType)(event.depositor, event.originChainId), recipient: (0, AddressUtils_1.toAddressType)(event.recipient, destinationChainId), inputToken: (0, AddressUtils_1.toAddressType)(event.inputToken, event.originChainId), outputToken: (0, AddressUtils_1.toAddressType)(event.outputToken, destinationChainId), exclusiveRelayer: (0, AddressUtils_1.toAddressType)(event.exclusiveRelayer, destinationChainId), relayer: (0, AddressUtils_1.toAddressType)(event.relayer, event.repaymentChainId), relayExecutionInfo: tslib_1.__assign(tslib_1.__assign({}, event.relayExecutionInfo), { updatedRecipient: (0, AddressUtils_1.toAddressType)(event.relayExecutionInfo.updatedRecipient, destinationChainId) }) });
}
function getRelayDataHash(relayData, destinationChainId) {
    var abi = [
        {
            type: "tuple",
            components: [
                { type: "bytes32", name: "depositor" },
                { type: "bytes32", name: "recipient" },
                { type: "bytes32", name: "exclusiveRelayer" },
                { type: "bytes32", name: "inputToken" },
                { type: "bytes32", name: "outputToken" },
                { type: "uint256", name: "inputAmount" },
                { type: "uint256", name: "outputAmount" },
                { type: "uint256", name: "originChainId" },
                { type: "uint256", name: "depositId" },
                { type: "uint32", name: "fillDeadline" },
                { type: "uint32", name: "exclusivityDeadline" },
                { type: "bytes", name: "message" },
            ],
        },
        { type: "uint256", name: "destinationChainId" },
    ];
    var _relayData = tslib_1.__assign(tslib_1.__assign({}, relayData), { depositor: relayData.depositor.toBytes32(), recipient: relayData.recipient.toBytes32(), inputToken: relayData.inputToken.toBytes32(), outputToken: relayData.outputToken.toBytes32(), exclusiveRelayer: relayData.exclusiveRelayer.toBytes32() });
    if ((0, NetworkUtils_1.chainIsSvm)(destinationChainId)) {
        var messageHash = getMessageHash(relayData.message);
        return arch_1.svm.getRelayDataHash(tslib_1.__assign(tslib_1.__assign({}, relayData), { messageHash: messageHash }), destinationChainId);
    }
    return (0, viem_1.keccak256)((0, viem_1.encodeAbiParameters)(abi, [_relayData, destinationChainId]));
}
function getRelayHashFromEvent(e) {
    return getRelayDataHash(e, e.destinationChainId);
}
function isUnsafeDepositId(depositId) {
    var maxSafeDepositId = BigNumberUtils_1.BigNumber.from(constants_1.MAX_SAFE_DEPOSIT_ID);
    return maxSafeDepositId.lt(depositId);
}
function getMessageHash(message) {
    return (0, DepositUtils_1.isMessageEmpty)(message) ? constants_1.ZERO_BYTES : (0, viem_1.keccak256)(message);
}
function findInvalidFills(spokePoolClients) {
    return tslib_1.__awaiter(this, void 0, void 0, function () {
        var invalidFills, _i, _a, spokePoolClient, fills, fillDepositPairs, _b, fillDepositPairs_1, pair;
        var _this = this;
        return tslib_1.__generator(this, function (_c) {
            switch (_c.label) {
                case 0:
                    invalidFills = [];
                    _i = 0, _a = Object.values(spokePoolClients);
                    _c.label = 1;
                case 1:
                    if (!(_i < _a.length)) return [3, 4];
                    spokePoolClient = _a[_i];
                    fills = spokePoolClient.getFills();
                    return [4, Promise.all(fills.map(function (fill) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
                            var depositResult, validationResult;
                            var _a;
                            return tslib_1.__generator(this, function (_b) {
                                switch (_b.label) {
                                    case 0:
                                        if (isUnsafeDepositId(fill.depositId)) {
                                            return [2, null];
                                        }
                                        return [4, ((_a = spokePoolClients[fill.originChainId]) === null || _a === void 0 ? void 0 : _a.findDeposit(fill.depositId))];
                                    case 1:
                                        depositResult = _b.sent();
                                        if (!(depositResult === null || depositResult === void 0 ? void 0 : depositResult.found)) {
                                            return [2, {
                                                    fill: fill,
                                                    deposit: null,
                                                    reason: "No ".concat((0, NetworkUtils_1.getNetworkName)(fill.originChainId), " deposit with depositId ").concat(fill.depositId, " found"),
                                                }];
                                        }
                                        validationResult = (0, DepositUtils_1.validateFillForDeposit)(fill, depositResult.deposit);
                                        if (!validationResult.valid) {
                                            return [2, {
                                                    fill: fill,
                                                    deposit: depositResult.deposit,
                                                    reason: validationResult.reason,
                                                }];
                                        }
                                        return [2, null];
                                }
                            });
                        }); }))];
                case 2:
                    fillDepositPairs = _c.sent();
                    for (_b = 0, fillDepositPairs_1 = fillDepositPairs; _b < fillDepositPairs_1.length; _b++) {
                        pair = fillDepositPairs_1[_b];
                        if (pair) {
                            invalidFills.push({
                                fill: pair.fill,
                                reason: pair.reason,
                                deposit: pair.deposit || undefined,
                            });
                        }
                    }
                    _c.label = 3;
                case 3:
                    _i++;
                    return [3, 1];
                case 4: return [2, invalidFills];
            }
        });
    });
}
//# sourceMappingURL=SpokeUtils.js.map