"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.winston = exports.utf8ToHex = exports.toWei = exports.toBNWei = exports.toBN = exports.sinon = exports.expect = exports.chaiAssert = exports.chai = exports.Contract = exports.BigNumber = exports.deploySpokePool = exports.spokePoolFixture = exports.deployHubPool = exports.hubPoolFixture = exports.getContractFactory = exports.getParamType = exports.buildV3SlowRelayTree = exports.buildSlowRelayTree = exports.buildRelayerRefundLeaves = exports.buildRelayerRefundTree = exports.buildPoolRebalanceLeaves = exports.buildPoolRebalanceLeafTree = exports.zeroAddress = exports.randomAddress = exports.modifyRelayHelper = exports.getUpdatedV3DepositSignature = exports.getDepositParams = void 0;
exports.deepEqualsWithBigNumber = deepEqualsWithBigNumber;
exports.assertPromiseError = assertPromiseError;
exports.assertPromisePasses = assertPromisePasses;
exports.setupTokensForWallet = setupTokensForWallet;
exports.createSpyLogger = createSpyLogger;
exports.deploySpokePoolWithToken = deploySpokePoolWithToken;
exports.deployConfigStore = deployConfigStore;
exports.deployAndConfigureHubPool = deployAndConfigureHubPool;
exports.enableRoutesOnHubPool = enableRoutesOnHubPool;
exports.appendMessageToResult = appendMessageToResult;
exports.getLastBlockTime = getLastBlockTime;
exports.addLiquidity = addLiquidity;
exports.deposit = deposit;
exports.depositV3 = depositV3;
exports.requestV3SlowFill = requestV3SlowFill;
exports.fillRelay = fillRelay;
exports.getLastBlockNumber = getLastBlockNumber;
exports.convertMockedConfigClient = convertMockedConfigClient;
exports.bigNumberFormatter = bigNumberFormatter;
exports.buildDepositForRelayerFeeTest = buildDepositForRelayerFeeTest;
var tslib_1 = require("tslib");
var utils = tslib_1.__importStar(require("@across-protocol/contracts/dist/test-utils"));
var assert_1 = tslib_1.__importDefault(require("assert"));
var chai_1 = tslib_1.__importStar(require("chai"));
exports.chai = chai_1.default;
Object.defineProperty(exports, "expect", { enumerable: true, get: function () { return chai_1.expect; } });
var chai_exclude_1 = tslib_1.__importDefault(require("chai-exclude"));
var ethers_1 = require("ethers");
Object.defineProperty(exports, "Contract", { enumerable: true, get: function () { return ethers_1.Contract; } });
var lodash_1 = tslib_1.__importDefault(require("lodash"));
var sinon_1 = tslib_1.__importDefault(require("sinon"));
exports.sinon = sinon_1.default;
var winston_1 = tslib_1.__importDefault(require("winston"));
exports.winston = winston_1.default;
var clients_1 = require("../../src/clients");
var constants_1 = require("../../src/constants");
var utils_1 = require("../../src/utils");
Object.defineProperty(exports, "BigNumber", { enumerable: true, get: function () { return utils_1.BigNumber; } });
Object.defineProperty(exports, "toBN", { enumerable: true, get: function () { return utils_1.toBN; } });
Object.defineProperty(exports, "toBNWei", { enumerable: true, get: function () { return utils_1.toBNWei; } });
Object.defineProperty(exports, "toWei", { enumerable: true, get: function () { return utils_1.toWei; } });
Object.defineProperty(exports, "utf8ToHex", { enumerable: true, get: function () { return utils_1.utf8ToHex; } });
var constants_2 = require("../constants");
var SpyTransport_1 = require("./SpyTransport");
chai_1.default.use(chai_exclude_1.default);
var chaiAssert = chai_1.default.assert;
exports.chaiAssert = chaiAssert;
exports.getDepositParams = utils.getDepositParams, exports.getUpdatedV3DepositSignature = utils.getUpdatedV3DepositSignature, exports.modifyRelayHelper = utils.modifyRelayHelper, exports.randomAddress = utils.randomAddress, exports.zeroAddress = utils.zeroAddress;
var MerkleLib_utils_1 = require("./MerkleLib.utils");
Object.defineProperty(exports, "buildPoolRebalanceLeafTree", { enumerable: true, get: function () { return MerkleLib_utils_1.buildPoolRebalanceLeafTree; } });
Object.defineProperty(exports, "buildPoolRebalanceLeaves", { enumerable: true, get: function () { return MerkleLib_utils_1.buildPoolRebalanceLeaves; } });
Object.defineProperty(exports, "buildRelayerRefundTree", { enumerable: true, get: function () { return MerkleLib_utils_1.buildRelayerRefundTree; } });
Object.defineProperty(exports, "buildRelayerRefundLeaves", { enumerable: true, get: function () { return MerkleLib_utils_1.buildRelayerRefundLeaves; } });
Object.defineProperty(exports, "buildSlowRelayTree", { enumerable: true, get: function () { return MerkleLib_utils_1.buildSlowRelayTree; } });
Object.defineProperty(exports, "buildV3SlowRelayTree", { enumerable: true, get: function () { return MerkleLib_utils_1.buildV3SlowRelayTree; } });
Object.defineProperty(exports, "getParamType", { enumerable: true, get: function () { return MerkleLib_utils_1.getParamType; } });
var getContractFactory_1 = require("./getContractFactory");
Object.defineProperty(exports, "getContractFactory", { enumerable: true, get: function () { return getContractFactory_1.getContractFactory; } });
var HubPool_Fixture_1 = require("../fixtures/HubPool.Fixture");
Object.defineProperty(exports, "hubPoolFixture", { enumerable: true, get: function () { return HubPool_Fixture_1.hubPoolFixture; } });
Object.defineProperty(exports, "deployHubPool", { enumerable: true, get: function () { return HubPool_Fixture_1.deployHubPool; } });
var SpokePool_Fixture_1 = require("../fixtures/SpokePool.Fixture");
Object.defineProperty(exports, "spokePoolFixture", { enumerable: true, get: function () { return SpokePool_Fixture_1.spokePoolFixture; } });
Object.defineProperty(exports, "deploySpokePool", { enumerable: true, get: function () { return SpokePool_Fixture_1.deploySpokePool; } });
var TokenRolesEnum = {
    OWNER: "0",
    MINTER: "1",
    BURNER: "3",
};
function deepEqualsWithBigNumber(x, y, omitKeys) {
    if (omitKeys === void 0) { omitKeys = []; }
    if (x === undefined || y === undefined || x === null || y === null) {
        return false;
    }
    var xObj = x;
    var yObj = y;
    var sortedKeysX = Object.fromEntries(Object.keys(xObj)
        .sort()
        .map(function (key) { return [key, xObj[key]]; }));
    var sortedKeysY = Object.fromEntries(Object.keys(yObj)
        .sort()
        .map(function (key) { return [key, yObj[key]]; }));
    chaiAssert.deepStrictEqual(lodash_1.default.omit(sortedKeysX, omitKeys), lodash_1.default.omit(sortedKeysY, omitKeys));
    return true;
}
function assertPromiseError(promise, errMessage) {
    return tslib_1.__awaiter(this, void 0, void 0, function () {
        var SPECIAL_ERROR_MESSAGE, e_1, err;
        return tslib_1.__generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    SPECIAL_ERROR_MESSAGE = "Promise didn't fail";
                    _a.label = 1;
                case 1:
                    _a.trys.push([1, 3, , 4]);
                    return [4, promise];
                case 2:
                    _a.sent();
                    throw new Error(SPECIAL_ERROR_MESSAGE);
                case 3:
                    e_1 = _a.sent();
                    err = e_1;
                    if (err.message.includes(SPECIAL_ERROR_MESSAGE)) {
                        throw err;
                    }
                    if (errMessage) {
                        chaiAssert.isTrue(err.message.includes(errMessage));
                    }
                    return [3, 4];
                case 4: return [2];
            }
        });
    });
}
function assertPromisePasses(promise) {
    return tslib_1.__awaiter(this, void 0, void 0, function () {
        var e_2, err;
        return tslib_1.__generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    _a.trys.push([0, 2, , 3]);
                    return [4, promise];
                case 1:
                    _a.sent();
                    return [3, 3];
                case 2:
                    e_2 = _a.sent();
                    err = e_2;
                    throw new Error("Promise failed: " + err.message);
                case 3: return [2];
            }
        });
    });
}
function setupTokensForWallet(contractToApprove_1, wallet_1, tokens_1, weth_1) {
    return tslib_1.__awaiter(this, arguments, void 0, function (contractToApprove, wallet, tokens, weth, seedMultiplier) {
        var approveToken;
        var _this = this;
        if (seedMultiplier === void 0) { seedMultiplier = 1; }
        return tslib_1.__generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    approveToken = function (token) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
                        var balance;
                        return tslib_1.__generator(this, function (_a) {
                            switch (_a.label) {
                                case 0: return [4, token.balanceOf(wallet.address)];
                                case 1:
                                    balance = _a.sent();
                                    return [4, token.connect(wallet).approve(contractToApprove.address, balance)];
                                case 2:
                                    _a.sent();
                                    return [2];
                            }
                        });
                    }); };
                    return [4, utils.seedWallet(wallet, tokens, weth, utils.amountToSeedWallets.mul(seedMultiplier))];
                case 1:
                    _a.sent();
                    return [4, Promise.all(tokens.map(approveToken))];
                case 2:
                    _a.sent();
                    if (!weth) return [3, 4];
                    return [4, approveToken(weth)];
                case 3:
                    _a.sent();
                    _a.label = 4;
                case 4: return [2];
            }
        });
    });
}
function createSpyLogger() {
    var spy = sinon_1.default.spy();
    var spyLogger = winston_1.default.createLogger({
        level: "debug",
        format: winston_1.default.format.combine(winston_1.default.format(bigNumberFormatter)(), winston_1.default.format.json()),
        transports: [
            new SpyTransport_1.SpyTransport({ level: "debug" }, { spy: spy }),
            process.env.LOG_IN_TEST ? new winston_1.default.transports.Console() : null,
        ].filter(function (n) { return n; }),
    });
    return { spy: spy, spyLogger: spyLogger };
}
function deploySpokePoolWithToken() {
    return tslib_1.__awaiter(this, arguments, void 0, function (fromChainId) {
        var _a, weth, erc20, spokePool, unwhitelistedErc20, destErc20, receipt;
        if (fromChainId === void 0) { fromChainId = 0; }
        return tslib_1.__generator(this, function (_b) {
            switch (_b.label) {
                case 0: return [4, (0, SpokePool_Fixture_1.deploySpokePool)(utils.ethers)];
                case 1:
                    _a = _b.sent(), weth = _a.weth, erc20 = _a.erc20, spokePool = _a.spokePool, unwhitelistedErc20 = _a.unwhitelistedErc20, destErc20 = _a.destErc20;
                    return [4, spokePool.deployTransaction.wait()];
                case 2:
                    receipt = _b.sent();
                    return [4, spokePool.setChainId(fromChainId == 0 ? utils.originChainId : fromChainId)];
                case 3:
                    _b.sent();
                    return [2, { weth: weth, erc20: erc20, spokePool: spokePool, unwhitelistedErc20: unwhitelistedErc20, destErc20: destErc20, deploymentBlock: receipt.blockNumber }];
            }
        });
    });
}
function deployConfigStore(signer_1, tokensToAdd_1) {
    return tslib_1.__awaiter(this, arguments, void 0, function (signer, tokensToAdd, maxL1TokensPerPoolRebalanceLeaf, maxRefundPerRelayerRefundLeaf, rateModel, additionalChainIdIndices) {
        var configStore, deploymentBlock, _i, tokensToAdd_2, token;
        if (maxL1TokensPerPoolRebalanceLeaf === void 0) { maxL1TokensPerPoolRebalanceLeaf = constants_2.MAX_L1_TOKENS_PER_POOL_REBALANCE_LEAF; }
        if (maxRefundPerRelayerRefundLeaf === void 0) { maxRefundPerRelayerRefundLeaf = constants_2.MAX_REFUNDS_PER_RELAYER_REFUND_LEAF; }
        if (rateModel === void 0) { rateModel = constants_2.sampleRateModel; }
        return tslib_1.__generator(this, function (_a) {
            switch (_a.label) {
                case 0: return [4, (0, getContractFactory_1.getContractFactory)("AcrossConfigStore", signer)];
                case 1: return [4, (_a.sent()).deploy()];
                case 2:
                    configStore = (_a.sent());
                    return [4, configStore.deployTransaction.wait()];
                case 3:
                    deploymentBlock = (_a.sent()).blockNumber;
                    _i = 0, tokensToAdd_2 = tokensToAdd;
                    _a.label = 4;
                case 4:
                    if (!(_i < tokensToAdd_2.length)) return [3, 7];
                    token = tokensToAdd_2[_i];
                    return [4, configStore.updateTokenConfig(token.address, JSON.stringify({
                            rateModel: rateModel,
                        }))];
                case 5:
                    _a.sent();
                    _a.label = 6;
                case 6:
                    _i++;
                    return [3, 4];
                case 7: return [4, configStore.updateGlobalConfig((0, utils_1.utf8ToHex)(clients_1.GLOBAL_CONFIG_STORE_KEYS.MAX_POOL_REBALANCE_LEAF_SIZE), maxL1TokensPerPoolRebalanceLeaf.toString())];
                case 8:
                    _a.sent();
                    return [4, configStore.updateGlobalConfig((0, utils_1.utf8ToHex)(clients_1.GLOBAL_CONFIG_STORE_KEYS.MAX_RELAYER_REPAYMENT_LEAF_SIZE), maxRefundPerRelayerRefundLeaf.toString())];
                case 9:
                    _a.sent();
                    if (!additionalChainIdIndices) return [3, 11];
                    return [4, configStore.updateGlobalConfig((0, utils_1.utf8ToHex)(clients_1.GLOBAL_CONFIG_STORE_KEYS.CHAIN_ID_INDICES), JSON.stringify(tslib_1.__spreadArray(tslib_1.__spreadArray([], constants_1.PROTOCOL_DEFAULT_CHAIN_ID_INDICES, true), additionalChainIdIndices, true)))];
                case 10:
                    _a.sent();
                    _a.label = 11;
                case 11: return [2, { configStore: configStore, deploymentBlock: deploymentBlock }];
            }
        });
    });
}
function deployAndConfigureHubPool(signer_1, spokePools_1) {
    return tslib_1.__awaiter(this, arguments, void 0, function (signer, spokePools, finderAddress, timerAddress) {
        var lpTokenFactory, hubPool, receipt, mockAdapter, _i, spokePools_2, spokePool, l1Token_1, l1Token_2;
        if (finderAddress === void 0) { finderAddress = exports.zeroAddress; }
        if (timerAddress === void 0) { timerAddress = exports.zeroAddress; }
        return tslib_1.__generator(this, function (_a) {
            switch (_a.label) {
                case 0: return [4, (0, getContractFactory_1.getContractFactory)("LpTokenFactory", signer)];
                case 1: return [4, (_a.sent()).deploy()];
                case 2:
                    lpTokenFactory = _a.sent();
                    return [4, (0, getContractFactory_1.getContractFactory)("HubPool", signer)];
                case 3: return [4, (_a.sent()).deploy(lpTokenFactory.address, finderAddress, exports.zeroAddress, timerAddress)];
                case 4:
                    hubPool = _a.sent();
                    return [4, hubPool.deployTransaction.wait()];
                case 5:
                    receipt = _a.sent();
                    return [4, (0, getContractFactory_1.getContractFactory)("Mock_Adapter", signer)];
                case 6: return [4, (_a.sent()).deploy()];
                case 7:
                    mockAdapter = _a.sent();
                    _i = 0, spokePools_2 = spokePools;
                    _a.label = 8;
                case 8:
                    if (!(_i < spokePools_2.length)) return [3, 11];
                    spokePool = spokePools_2[_i];
                    return [4, hubPool.setCrossChainContracts(spokePool.l2ChainId, mockAdapter.address, spokePool.spokePool.address)];
                case 9:
                    _a.sent();
                    _a.label = 10;
                case 10:
                    _i++;
                    return [3, 8];
                case 11: return [4, (0, getContractFactory_1.getContractFactory)("ExpandedERC20", signer)];
                case 12: return [4, (_a.sent()).deploy("L1Token1", "L1Token1", 18)];
                case 13:
                    l1Token_1 = _a.sent();
                    return [4, l1Token_1.addMember(TokenRolesEnum.MINTER, signer.address)];
                case 14:
                    _a.sent();
                    return [4, (0, getContractFactory_1.getContractFactory)("ExpandedERC20", signer)];
                case 15: return [4, (_a.sent()).deploy("L1Token2", "L1Token2", 18)];
                case 16:
                    l1Token_2 = _a.sent();
                    return [4, l1Token_2.addMember(TokenRolesEnum.MINTER, signer.address)];
                case 17:
                    _a.sent();
                    return [2, { hubPool: hubPool, mockAdapter: mockAdapter, l1Token_1: l1Token_1, l1Token_2: l1Token_2, hubPoolDeploymentBlock: receipt.blockNumber }];
            }
        });
    });
}
function enableRoutesOnHubPool(hubPool, rebalanceRouteTokens) {
    return tslib_1.__awaiter(this, void 0, void 0, function () {
        var _i, rebalanceRouteTokens_1, tkn;
        return tslib_1.__generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    _i = 0, rebalanceRouteTokens_1 = rebalanceRouteTokens;
                    _a.label = 1;
                case 1:
                    if (!(_i < rebalanceRouteTokens_1.length)) return [3, 5];
                    tkn = rebalanceRouteTokens_1[_i];
                    return [4, hubPool.setPoolRebalanceRoute(tkn.destinationChainId, tkn.l1Token.address, tkn.destinationToken.address)];
                case 2:
                    _a.sent();
                    return [4, hubPool.enableL1TokenForLiquidityProvision(tkn.l1Token.address)];
                case 3:
                    _a.sent();
                    _a.label = 4;
                case 4:
                    _i++;
                    return [3, 1];
                case 5: return [2];
            }
        });
    });
}
function appendMessageToResult(body) {
    return tslib_1.__assign(tslib_1.__assign({}, body), { message: "" });
}
function getLastBlockTime(provider) {
    return tslib_1.__awaiter(this, void 0, void 0, function () {
        var _a, _b;
        return tslib_1.__generator(this, function (_c) {
            switch (_c.label) {
                case 0:
                    _b = (_a = provider).getBlock;
                    return [4, provider.getBlockNumber()];
                case 1: return [4, _b.apply(_a, [_c.sent()])];
                case 2: return [2, (_c.sent()).timestamp];
            }
        });
    });
}
function addLiquidity(signer, hubPool, l1Token, amount) {
    return tslib_1.__awaiter(this, void 0, void 0, function () {
        return tslib_1.__generator(this, function (_a) {
            switch (_a.label) {
                case 0: return [4, utils.seedWallet(signer, [l1Token], undefined, amount)];
                case 1:
                    _a.sent();
                    return [4, l1Token.connect(signer).approve(hubPool.address, amount)];
                case 2:
                    _a.sent();
                    return [4, hubPool.enableL1TokenForLiquidityProvision(l1Token.address)];
                case 3:
                    _a.sent();
                    return [4, hubPool.connect(signer).addLiquidity(l1Token.address, amount)];
                case 4:
                    _a.sent();
                    return [2];
            }
        });
    });
}
function deposit(spokePool, destinationChainId, signer, inputToken, inputAmount, outputToken, outputAmount, opts) {
    if (opts === void 0) { opts = {}; }
    return _deposit(spokePool, destinationChainId, signer, inputToken, inputAmount, outputToken, outputAmount, tslib_1.__assign(tslib_1.__assign({}, opts), { addressModifier: utils_1.toBytes32 }));
}
function depositV3(spokePool, destinationChainId, signer, inputToken, inputAmount, outputToken, outputAmount, opts) {
    if (opts === void 0) { opts = {}; }
    return _deposit(spokePool, destinationChainId, signer, inputToken, inputAmount, outputToken, outputAmount, tslib_1.__assign(tslib_1.__assign({}, opts), { addressModifier: utils_1.toEvmAddress }));
}
function _deposit(spokePool_1, destinationChainId_1, signer_1, inputToken_1, inputAmount_1, outputToken_1, outputAmount_1) {
    return tslib_1.__awaiter(this, arguments, void 0, function (spokePool, destinationChainId, signer, inputToken, inputAmount, outputToken, outputAmount, opts) {
        var depositor, _a, _b, recipient, _c, spokePoolTime, fillDeadlineBuffer, quoteTimestamp, message, fillDeadline, exclusivityDeadline, exclusiveRelayer, getChainId, _d, events, originChainId, lastEvent, args, _e, blockNumber, transactionHash, transactionIndex, logIndex;
        var _this = this;
        var _f, _g, _h, _j, _k, _l;
        if (opts === void 0) { opts = {}; }
        return tslib_1.__generator(this, function (_m) {
            switch (_m.label) {
                case 0:
                    _a = utils_1.toAddressType;
                    _b = [signer.address];
                    return [4, spokePool.chainId()];
                case 1:
                    depositor = _a.apply(void 0, _b.concat([_m.sent()]));
                    recipient = (_f = opts.recipient) !== null && _f !== void 0 ? _f : depositor;
                    return [4, Promise.all([spokePool.getCurrentTime(), spokePool.fillDeadlineBuffer()])];
                case 2:
                    _c = (_m.sent()).map(function (n) { return Number(n); }), spokePoolTime = _c[0], fillDeadlineBuffer = _c[1];
                    quoteTimestamp = (_g = opts.quoteTimestamp) !== null && _g !== void 0 ? _g : spokePoolTime;
                    message = (_h = opts.message) !== null && _h !== void 0 ? _h : constants_1.EMPTY_MESSAGE;
                    fillDeadline = (_j = opts.fillDeadline) !== null && _j !== void 0 ? _j : spokePoolTime + fillDeadlineBuffer;
                    exclusivityDeadline = (_k = opts.exclusivityDeadline) !== null && _k !== void 0 ? _k : 0;
                    exclusiveRelayer = (_l = opts.exclusiveRelayer) !== null && _l !== void 0 ? _l : (0, utils_1.toAddressType)(exports.zeroAddress, destinationChainId);
                    return [4, spokePool
                            .connect(signer)
                            .deposit(depositor.toBytes32(), recipient.toBytes32(), inputToken.toBytes32(), outputToken.toBytes32(), inputAmount, outputAmount, destinationChainId, exclusiveRelayer.toBytes32(), quoteTimestamp, fillDeadline, exclusivityDeadline, message)];
                case 3:
                    _m.sent();
                    getChainId = function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { var _a, _b, _c; return tslib_1.__generator(this, function (_d) {
                        switch (_d.label) {
                            case 0:
                                _b = (_a = Promise).resolve;
                                _c = Number;
                                return [4, spokePool.chainId()];
                            case 1: return [2, _b.apply(_a, [_c.apply(void 0, [_d.sent()])])];
                        }
                    }); }); };
                    return [4, Promise.all([
                            spokePool.queryFilter(spokePool.filters.FundsDeposited()),
                            getChainId(),
                        ])];
                case 4:
                    _d = _m.sent(), events = _d[0], originChainId = _d[1];
                    lastEvent = events.at(-1);
                    args = lastEvent === null || lastEvent === void 0 ? void 0 : lastEvent.args;
                    chaiAssert.exists(args);
                    args = args;
                    _e = lastEvent, blockNumber = _e.blockNumber, transactionHash = _e.transactionHash, transactionIndex = _e.transactionIndex, logIndex = _e.logIndex;
                    (0, assert_1.default)(args.destinationChainId.toNumber() === destinationChainId);
                    return [2, {
                            depositId: (0, utils_1.toBN)(args.depositId),
                            originChainId: originChainId,
                            destinationChainId: destinationChainId,
                            depositor: (0, utils_1.toAddressType)(args.depositor, originChainId),
                            recipient: (0, utils_1.toAddressType)(args.recipient, destinationChainId),
                            inputToken: (0, utils_1.toAddressType)(args.inputToken, originChainId),
                            inputAmount: args.inputAmount,
                            outputToken: (0, utils_1.toAddressType)(args.outputToken, destinationChainId),
                            outputAmount: args.outputAmount,
                            quoteTimestamp: args.quoteTimestamp,
                            message: args.message,
                            messageHash: (0, utils_1.getMessageHash)(args.message),
                            fillDeadline: args.fillDeadline,
                            exclusivityDeadline: args.exclusivityDeadline,
                            exclusiveRelayer: (0, utils_1.toAddressType)(args.exclusiveRelayer, destinationChainId),
                            fromLiteChain: false,
                            toLiteChain: false,
                            quoteBlockNumber: 0,
                            blockNumber: blockNumber,
                            txnRef: transactionHash,
                            txnIndex: transactionIndex,
                            logIndex: logIndex,
                        }];
            }
        });
    });
}
function requestV3SlowFill(spokePool, relayData, signer) {
    return tslib_1.__awaiter(this, void 0, void 0, function () {
        var destinationChainId, _a, events, lastEvent, _b, blockNumber, transactionHash, transactionIndex, logIndex, args, originChainId;
        return tslib_1.__generator(this, function (_c) {
            switch (_c.label) {
                case 0:
                    _a = Number;
                    return [4, spokePool.chainId()];
                case 1:
                    destinationChainId = _a.apply(void 0, [_c.sent()]);
                    chaiAssert.notEqual(relayData.originChainId, destinationChainId);
                    return [4, spokePool.connect(signer).requestSlowFill(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() }))];
                case 2:
                    _c.sent();
                    return [4, spokePool.queryFilter(spokePool.filters.RequestedSlowFill())];
                case 3:
                    events = _c.sent();
                    lastEvent = events.at(-1);
                    (0, chai_1.expect)(lastEvent).to.exist;
                    _b = lastEvent, blockNumber = _b.blockNumber, transactionHash = _b.transactionHash, transactionIndex = _b.transactionIndex, logIndex = _b.logIndex;
                    (0, chai_1.expect)(lastEvent.args).to.exist;
                    args = lastEvent.args;
                    originChainId = Number(args.originChainId);
                    return [2, {
                            depositId: (0, utils_1.toBN)(args.depositId),
                            originChainId: originChainId,
                            destinationChainId: destinationChainId,
                            depositor: (0, utils_1.toAddressType)(args.depositor, originChainId),
                            recipient: (0, utils_1.toAddressType)(args.recipient, destinationChainId),
                            inputToken: (0, utils_1.toAddressType)(args.inputToken, originChainId),
                            inputAmount: args.inputAmount,
                            outputToken: (0, utils_1.toAddressType)(args.outputToken, destinationChainId),
                            outputAmount: args.outputAmount,
                            messageHash: (0, utils_1.getMessageHash)(args.message),
                            fillDeadline: args.fillDeadline,
                            exclusivityDeadline: args.exclusivityDeadline,
                            exclusiveRelayer: (0, utils_1.toAddressType)(args.exclusiveRelayer, destinationChainId),
                            blockNumber: blockNumber,
                            txnRef: transactionHash,
                            txnIndex: transactionIndex,
                            logIndex: logIndex,
                        }];
            }
        });
    });
}
function fillRelay(spokePool, _deposit, signer, repayment) {
    return tslib_1.__awaiter(this, void 0, void 0, function () {
        var destinationChainId, _a, deposit, repaymentAddress, events, lastEvent, args, _b, blockNumber, transactionHash, transactionIndex, logIndex;
        var _c, _d;
        return tslib_1.__generator(this, function (_e) {
            switch (_e.label) {
                case 0:
                    _a = Number;
                    return [4, spokePool.chainId()];
                case 1:
                    destinationChainId = _a.apply(void 0, [_e.sent()]);
                    chaiAssert.notEqual(_deposit.originChainId, destinationChainId);
                    deposit = tslib_1.__assign(tslib_1.__assign({}, _deposit), { depositor: _deposit.depositor.toBytes32(), recipient: _deposit.recipient.toBytes32(), exclusiveRelayer: _deposit.exclusiveRelayer.toBytes32(), inputToken: _deposit.inputToken.toBytes32(), outputToken: _deposit.outputToken.toBytes32() });
                    repaymentAddress = (_c = repayment === null || repayment === void 0 ? void 0 : repayment.repaymentAddress.toBytes32()) !== null && _c !== void 0 ? _c : (0, utils_1.toBytes32)(signer.address);
                    return [4, spokePool
                            .connect(signer)
                            .fillRelay(deposit, (_d = repayment === null || repayment === void 0 ? void 0 : repayment.repaymentChainId) !== null && _d !== void 0 ? _d : destinationChainId, repaymentAddress)];
                case 2:
                    _e.sent();
                    return [4, spokePool.queryFilter(spokePool.filters.FilledRelay())];
                case 3:
                    events = _e.sent();
                    lastEvent = events.at(-1);
                    args = lastEvent.args;
                    chaiAssert.exists(args);
                    args = args;
                    _b = lastEvent, blockNumber = _b.blockNumber, transactionHash = _b.transactionHash, transactionIndex = _b.transactionIndex, logIndex = _b.logIndex;
                    return [2, {
                            depositId: (0, utils_1.toBN)(args.depositId),
                            originChainId: Number(args.originChainId),
                            destinationChainId: destinationChainId,
                            depositor: (0, utils_1.toAddressType)(args.depositor, args.originChainId),
                            recipient: (0, utils_1.toAddressType)(args.recipient, destinationChainId),
                            inputToken: (0, utils_1.toAddressType)(args.inputToken, args.originChainId),
                            inputAmount: args.inputAmount,
                            outputToken: (0, utils_1.toAddressType)(args.outputToken, destinationChainId),
                            outputAmount: args.outputAmount,
                            messageHash: (0, utils_1.getMessageHash)(args.message),
                            fillDeadline: args.fillDeadline,
                            exclusivityDeadline: args.exclusivityDeadline,
                            exclusiveRelayer: (0, utils_1.toAddressType)(args.exclusiveRelayer, destinationChainId),
                            relayer: args.relayer,
                            repaymentChainId: Number(args.repaymentChainId),
                            relayExecutionInfo: {
                                updatedRecipient: (0, utils_1.toAddressType)(args.relayExecutionInfo.updatedRecipient, destinationChainId),
                                updatedMessageHash: args.relayExecutionInfo.updatedMessageHash,
                                updatedOutputAmount: args.relayExecutionInfo.updatedOutputAmount,
                                fillType: args.relayExecutionInfo.fillType,
                            },
                            blockNumber: blockNumber,
                            txnRef: transactionHash,
                            txnIndex: transactionIndex,
                            logIndex: logIndex,
                        }];
            }
        });
    });
}
function getLastBlockNumber() {
    return utils.ethers.provider.getBlockNumber();
}
function convertMockedConfigClient(_client) {
    return true;
}
function bigNumberFormatter(logEntry) {
    try {
        var out_1 = iterativelyReplaceBigNumbers(logEntry);
        if (out_1 !== logEntry)
            Object.getOwnPropertySymbols(logEntry).map(function (symbol) { return (out_1[symbol] = logEntry[symbol]); });
        return out_1;
    }
    catch (_) {
        return logEntry;
    }
}
var iterativelyReplaceBigNumbers = function (obj) {
    var replacements = Object.entries(obj).map(function (_a) {
        var key = _a[0], value = _a[1];
        if (utils_1.BigNumber.isBigNumber(value))
            return [key, value.toString()];
        else if (typeof value === "object" && value !== null)
            return [key, iterativelyReplaceBigNumbers(value)];
        else
            return [key, value];
    });
    var copyNeeded = replacements.some(function (_a) {
        var key = _a[0], value = _a[1];
        return obj[key] !== value;
    });
    return copyNeeded ? Object.fromEntries(replacements) : obj;
};
function buildDepositForRelayerFeeTest(amount, tokenSymbol, originChainId, toChainId) {
    var _inputToken = (0, utils_1.resolveContractFromSymbol)(tokenSymbol, originChainId);
    (0, assert_1.default)((0, utils_1.isDefined)(_inputToken), "".concat(tokenSymbol, " not found on ").concat(originChainId));
    var inputToken = (0, utils_1.toAddressType)(_inputToken, originChainId);
    var _outputToken = (0, utils_1.resolveContractFromSymbol)(tokenSymbol, toChainId);
    (0, assert_1.default)((0, utils_1.isDefined)(_outputToken), "".concat(tokenSymbol, " not found on ").concat(toChainId));
    var outputToken = (0, utils_1.toAddressType)(_outputToken, toChainId);
    var currentTime = (0, utils_1.getCurrentTime)();
    var message = constants_1.EMPTY_MESSAGE;
    return {
        depositId: utils_1.bnUint32Max,
        originChainId: originChainId,
        destinationChainId: toChainId,
        depositor: (0, utils_1.toAddressType)((0, exports.randomAddress)(), originChainId),
        recipient: (0, utils_1.toAddressType)((0, exports.randomAddress)(), toChainId),
        inputToken: inputToken,
        inputAmount: (0, utils_1.toBN)(amount),
        outputToken: outputToken,
        outputAmount: (0, utils_1.toBN)(amount).sub(utils_1.bnOne),
        message: message,
        messageHash: (0, utils_1.getMessageHash)(message),
        quoteTimestamp: currentTime,
        fillDeadline: currentTime + 7200,
        exclusivityDeadline: 0,
        exclusiveRelayer: (0, utils_1.toAddressType)(constants_1.ZERO_ADDRESS, toChainId),
        fromLiteChain: false,
        toLiteChain: false,
    };
}
//# sourceMappingURL=utils.js.map