"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MockSvmCpiEventsClient = void 0;
var tslib_1 = require("tslib");
var assert_1 = tslib_1.__importDefault(require("assert"));
var ethers_1 = require("ethers");
var crypto_1 = require("crypto");
var utils_1 = require("ethers/lib/utils");
var lodash_1 = require("lodash");
var kit_1 = require("@solana/kit");
var contracts_1 = require("@across-protocol/contracts");
var constants_1 = require("@across-protocol/constants");
var mocks_1 = require("../../providers/mocks");
var svm_1 = require("../../arch/svm");
var utils_2 = require("../../utils");
var interfaces_1 = require("../../interfaces");
var randomBytes = function (n) { return ethers_1.utils.hexlify(ethers_1.utils.randomBytes(n)); };
var MockSvmCpiEventsClient = (function (_super) {
    tslib_1.__extends(MockSvmCpiEventsClient, _super);
    function MockSvmCpiEventsClient(programId, chainId) {
        if (programId === void 0) { programId = contracts_1.SvmSpokeClient.SVM_SPOKE_PROGRAM_ADDRESS; }
        if (chainId === void 0) { chainId = constants_1.CHAIN_IDs.SOLANA; }
        var _this = _super.call(this, null, programId, null, null) || this;
        _this.events = {};
        _this.slotHeight = BigInt(0);
        _this.minBlockRange = 10;
        _this.numberOfDeposits = utils_2.bnZero;
        _this.chainId = chainId;
        return _this;
    }
    MockSvmCpiEventsClient.prototype.setSlotHeight = function (slotHeight) {
        this.slotHeight = slotHeight;
    };
    MockSvmCpiEventsClient.prototype.setEvents = function (events) {
        var _a;
        var _b, _c;
        for (var _i = 0, events_1 = events; _i < events_1.length; _i++) {
            var event_1 = events_1[_i];
            (_a = (_b = this.events)[_c = event_1.name]) !== null && _a !== void 0 ? _a : (_b[_c] = []);
            this.events[event_1.name].push(event_1);
        }
        var maxSlot = Math.max.apply(Math, events.map(function (event) { return Number(event.slot); }));
        this.setSlotHeight(BigInt(maxSlot) + BigInt(1));
    };
    MockSvmCpiEventsClient.prototype.clearEvents = function (name) {
        if (name) {
            this.events[name] = [];
        }
        else {
            this.events = {};
        }
    };
    MockSvmCpiEventsClient.prototype.queryEvents = function (eventName, fromSlot, toSlot) {
        var _a, _b;
        return Promise.resolve((_b = (_a = this.events[eventName]) === null || _a === void 0 ? void 0 : _a.filter(function (event) { return (!fromSlot || event.slot >= fromSlot) && (!toSlot || event.slot <= toSlot); })) !== null && _b !== void 0 ? _b : []);
    };
    MockSvmCpiEventsClient.prototype.getRpc = function () {
        var client = new mocks_1.MockSolanaRpcFactory("https://test.com", 1234567890);
        client.setResult("getSlot", [], this.slotHeight);
        return client.createRpcClient();
    };
    MockSvmCpiEventsClient.prototype.deposit = function (deposit) {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j;
        var slot = deposit.slot;
        var depositId = deposit.depositId, destinationChainId = deposit.destinationChainId, inputAmount = deposit.inputAmount, outputAmount = deposit.outputAmount;
        depositId !== null && depositId !== void 0 ? depositId : (depositId = (0, utils_1.arrayify)((0, utils_1.hexZeroPad)((0, utils_1.hexlify)((0, lodash_1.random)(1, 100000, false)), 32)));
        this.numberOfDeposits = this.numberOfDeposits.add(utils_2.bnOne);
        destinationChainId !== null && destinationChainId !== void 0 ? destinationChainId : (destinationChainId = BigInt((0, lodash_1.random)(1, 42161, false)));
        var depositor = (_a = deposit.depositor) !== null && _a !== void 0 ? _a : (0, svm_1.getRandomSvmAddress)();
        var recipient = (_b = deposit.recipient) !== null && _b !== void 0 ? _b : utils_2.SvmAddress.from(randomBytes(32)).toBase58();
        var inputToken = (_c = deposit.inputToken) !== null && _c !== void 0 ? _c : (0, svm_1.getRandomSvmAddress)();
        var outputToken = (_d = deposit.outputToken) !== null && _d !== void 0 ? _d : utils_2.SvmAddress.from(randomBytes(32)).toBase58();
        inputAmount !== null && inputAmount !== void 0 ? inputAmount : (inputAmount = BigInt((0, lodash_1.random)(1, 1000, false)));
        outputAmount !== null && outputAmount !== void 0 ? outputAmount : (outputAmount = (0, svm_1.bigToU8a32)((inputAmount * BigInt(95)) / BigInt(100)));
        var message = (_e = deposit.message) !== null && _e !== void 0 ? _e : new Uint8Array(32);
        var quoteTimestamp = (_f = deposit.quoteTimestamp) !== null && _f !== void 0 ? _f : (0, utils_2.getCurrentTime)();
        var args = {
            depositId: depositId,
            destinationChainId: destinationChainId,
            depositor: depositor,
            recipient: recipient,
            inputToken: inputToken,
            inputAmount: inputAmount,
            outputToken: outputToken,
            outputAmount: outputAmount,
            quoteTimestamp: quoteTimestamp,
            fillDeadline: (_g = deposit.fillDeadline) !== null && _g !== void 0 ? _g : quoteTimestamp + 3600,
            exclusiveRelayer: (_h = deposit.exclusiveRelayer) !== null && _h !== void 0 ? _h : svm_1.SVM_DEFAULT_ADDRESS,
            exclusivityDeadline: (_j = deposit.exclusivityDeadline) !== null && _j !== void 0 ? _j : quoteTimestamp + 600,
            message: message,
        };
        return this.generateEvent({
            event: svm_1.SVMEventNames.FundsDeposited,
            address: this.getProgramAddress(),
            args: args,
            slot: slot,
        });
    };
    MockSvmCpiEventsClient.prototype.fillRelay = function (fill) {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
        var slot = fill.slot;
        var depositId = fill.depositId, inputAmount = fill.inputAmount, outputAmount = fill.outputAmount, fillDeadline = fill.fillDeadline;
        depositId !== null && depositId !== void 0 ? depositId : (depositId = (0, utils_1.arrayify)((0, utils_1.hexZeroPad)((0, utils_1.hexlify)((0, lodash_1.random)(1, 100000, false)), 32)));
        var inputAmountBigInt = BigInt((0, lodash_1.random)(1, 1000, false));
        inputAmount !== null && inputAmount !== void 0 ? inputAmount : (inputAmount = (0, svm_1.bigToU8a32)(inputAmountBigInt));
        outputAmount !== null && outputAmount !== void 0 ? outputAmount : (outputAmount = (inputAmountBigInt * BigInt(95)) / BigInt(100));
        fillDeadline !== null && fillDeadline !== void 0 ? fillDeadline : (fillDeadline = (0, utils_2.getCurrentTime)() + 60);
        var depositor = (_a = fill.depositor) !== null && _a !== void 0 ? _a : utils_2.EvmAddress.from((0, utils_2.randomAddress)()).toBase58();
        var recipient = (_b = fill.recipient) !== null && _b !== void 0 ? _b : (0, svm_1.getRandomSvmAddress)();
        var inputToken = (_c = fill.inputToken) !== null && _c !== void 0 ? _c : utils_2.EvmAddress.from((0, utils_2.randomAddress)()).toBase58();
        var outputToken = (_d = fill.outputToken) !== null && _d !== void 0 ? _d : (0, svm_1.getRandomSvmAddress)();
        var messageHash = (_e = fill.messageHash) !== null && _e !== void 0 ? _e : new Uint8Array(32);
        var relayExecutionInfo = {
            updatedRecipient: (_g = (_f = fill.relayExecutionInfo) === null || _f === void 0 ? void 0 : _f.updatedRecipient) !== null && _g !== void 0 ? _g : recipient,
            updatedOutputAmount: (_j = (_h = fill.relayExecutionInfo) === null || _h === void 0 ? void 0 : _h.updatedOutputAmount) !== null && _j !== void 0 ? _j : outputAmount,
            fillType: (_l = (_k = fill.relayExecutionInfo) === null || _k === void 0 ? void 0 : _k.fillType) !== null && _l !== void 0 ? _l : interfaces_1.FillType.FastFill,
            updatedMessageHash: (_o = (_m = fill.relayExecutionInfo) === null || _m === void 0 ? void 0 : _m.updatedMessageHash) !== null && _o !== void 0 ? _o : messageHash,
        };
        var args = {
            depositId: depositId,
            originChainId: (_p = fill.originChainId) !== null && _p !== void 0 ? _p : BigInt((0, lodash_1.random)(1, 42161, false)),
            depositor: depositor,
            recipient: recipient,
            inputToken: inputToken,
            inputAmount: inputAmount,
            outputToken: outputToken,
            outputAmount: outputAmount,
            fillDeadline: fillDeadline,
            exclusiveRelayer: (_q = fill.exclusiveRelayer) !== null && _q !== void 0 ? _q : svm_1.SVM_DEFAULT_ADDRESS,
            exclusivityDeadline: (_r = fill.exclusivityDeadline) !== null && _r !== void 0 ? _r : fillDeadline,
            relayer: (_s = fill.relayer) !== null && _s !== void 0 ? _s : (0, svm_1.getRandomSvmAddress)(),
            messageHash: messageHash,
            relayExecutionInfo: relayExecutionInfo,
        };
        return this.generateEvent({
            event: svm_1.SVMEventNames.FilledRelay,
            address: this.getProgramAddress(),
            args: args,
            slot: slot,
        });
    };
    MockSvmCpiEventsClient.prototype.requestSlowFill = function (slowFillRequest) {
        var _a, _b, _c, _d, _e, _f, _g, _h;
        var slot = slowFillRequest.slot;
        var depositId = slowFillRequest.depositId, originChainId = slowFillRequest.originChainId;
        depositId !== null && depositId !== void 0 ? depositId : (depositId = Uint8Array.from([(0, lodash_1.random)(1, 100000, false)]));
        originChainId !== null && originChainId !== void 0 ? originChainId : (originChainId = BigInt((0, lodash_1.random)(1, 42161, false)));
        var depositor = (_a = slowFillRequest.depositor) !== null && _a !== void 0 ? _a : utils_2.SvmAddress.from(randomBytes(32)).toBase58();
        var recipient = (_b = slowFillRequest.recipient) !== null && _b !== void 0 ? _b : (0, svm_1.getRandomSvmAddress)();
        var inputToken = (_c = slowFillRequest.inputToken) !== null && _c !== void 0 ? _c : utils_2.SvmAddress.from(randomBytes(32)).toBase58();
        var outputToken = (_d = slowFillRequest.outputToken) !== null && _d !== void 0 ? _d : (0, svm_1.getRandomSvmAddress)();
        var args = tslib_1.__assign(tslib_1.__assign({}, slowFillRequest), { depositId: depositId, originChainId: originChainId, depositor: depositor, recipient: recipient, inputToken: inputToken, outputToken: outputToken, inputAmount: (_e = slowFillRequest.inputAmount) !== null && _e !== void 0 ? _e : BigInt((0, lodash_1.random)(1, 1000, false)), outputAmount: (_g = (_f = slowFillRequest.outputAmount) !== null && _f !== void 0 ? _f : slowFillRequest.inputAmount) !== null && _g !== void 0 ? _g : BigInt((0, lodash_1.random)(1, 1000, false)), exclusiveRelayer: (_h = slowFillRequest.exclusiveRelayer) !== null && _h !== void 0 ? _h : svm_1.SVM_DEFAULT_ADDRESS });
        return this.generateEvent({
            event: svm_1.SVMEventNames.RequestedSlowFill,
            address: this.getProgramAddress(),
            args: args,
            slot: slot,
        });
    };
    MockSvmCpiEventsClient.prototype.generateEvent = function (inputs) {
        var _this = this;
        var address = inputs.address, event = inputs.event, args = inputs.args;
        var slot = inputs.slot;
        var randomSlotWithinRange = function () {
            return (0, lodash_1.random)(Number(_this.slotHeight) + 1, Number(_this.slotHeight) + _this.minBlockRange, false);
        };
        slot !== null && slot !== void 0 ? slot : (slot = BigInt(randomSlotWithinRange()));
        (0, assert_1.default)(slot >= this.slotHeight, "".concat(slot, " < ").concat(this.slotHeight));
        this.slotHeight = slot;
        var generatedEvent = {
            name: event,
            slot: slot,
            signature: (0, kit_1.signature)(utils_2.bs58.encode(Uint8Array.from((0, crypto_1.createHash)("sha512")
                .update("Across-".concat(event, "-").concat(slot, "-").concat((0, lodash_1.random)(1, 100000)))
                .digest()))),
            program: address,
            data: args,
            confirmationStatus: "finalized",
            blockTime: BigInt(new Date().getTime()),
        };
        this.setEvents([generatedEvent]);
        return generatedEvent;
    };
    return MockSvmCpiEventsClient;
}(svm_1.SvmCpiEventsClient));
exports.MockSvmCpiEventsClient = MockSvmCpiEventsClient;
//# sourceMappingURL=MockSvmCpiEventsClient.js.map