"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isRemoteL3Supported = exports.isExoticBridgeNetworkId = exports.isCelestia = exports.isArbitrum = exports.isSEI = exports.isMonad = exports.isBNB = exports.isNonNativeEth = exports.isL3 = exports.isRemoteL3 = exports.PromiseTimeoutErrorMsg = void 0;
exports.sleep = sleep;
exports.sleepRandom = sleepRandom;
exports.randBetween = randBetween;
exports.removeLeadingZeroes = removeLeadingZeroes;
exports.addLeadingZeroes = addLeadingZeroes;
exports.decodeNetworkId = decodeNetworkId;
exports.decodeAsset = decodeAsset;
exports.encodeNetworkId = encodeNetworkId;
exports.parseAssetFromHex = parseAssetFromHex;
exports.parseAssetToHex = parseAssetToHex;
exports.racePromiseWithTimeout = racePromiseWithTimeout;
exports.initRemoteAttestationsBooks = initRemoteAttestationsBooks;
exports.initL3Network = initL3Network;
exports.waitTransmitterFinishProcessing = waitTransmitterFinishProcessing;
exports.setInfiniteAllowanceOnAssetForAddress = setInfiniteAllowanceOnAssetForAddress;
exports.shouldTrackLifecycleEvent = shouldTrackLifecycleEvent;
exports.restoreBigNumbers = restoreBigNumbers;
exports.generateOrderId = generateOrderId;
exports.createOrderDetails = createOrderDetails;
exports.encodeERC20Order = encodeERC20Order;
exports.encodeERC721MintOrder = encodeERC721MintOrder;
exports.fetchEnvVarOrThrow = fetchEnvVarOrThrow;
exports.generateIdFull = generateIdFull;
const logger_1 = require("./logger");
const ethers_1 = require("ethers");
const experimental_1 = require("@ethersproject/experimental");
const contract_1 = require("./contract");
const transmitter_service_1 = require("../transmitter/transmitter.service");
const types_1 = require("../pricer/types");
const helpers_1 = require("../pricer/helpers");
const error_1 = require("./error");
const flatted_1 = require("flatted");
/**
 * Sleep for a given number of seconds.
 *
 * @param {number}  seconds seconds to sleep for
 * @param {string=} reason reason for sleeping
 */
function sleep(seconds, reason) {
    logger_1.logger.trace({ reason }, `Sleeping for ${seconds} sec...`);
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve();
        }, seconds * 1000);
    });
}
/**
 * Sleep for a random number of seconds, between the given min and max.
 *
 * @param {number}  minSeconds Minimum seconds to sleep for
 * @param {number}  maxSeconds Maximum seconds to sleep for
 * @param {string=} reason reason for sleeping
 */
function sleepRandom(minSeconds, maxSeconds, reason) {
    return sleep(randBetween(minSeconds, maxSeconds), reason);
}
/**
 * Generate a random number between two given numbers.
 * By default, the result is fixed to 2 digits after the decimal point.
 *
 * @param {number}  min
 * @param {number}  max
 * @param {number=} precision
 * @returns {number}
 */
function randBetween(min, max, precision = 2) {
    const randomValue = Math.random();
    const result = min + randomValue * (max - min);
    return +result.toFixed(precision);
}
/**
 * Removes the leading 24 chars (12 bytes) from an address, making it an Ethereum address.
 *
 * @param {string} address
 * @return {string}
 */
function removeLeadingZeroes(address) {
    return '0x' + address.slice(26);
}
function addLeadingZeroes(address) {
    return '0x' + '0'.repeat(24) + address.slice(2);
}
/**
 * Decodes network from hex to network ID name.
 * E.g. 0x6f707374 --> opsp
 *
 * @param {string}  encodedNetworkId
 * @returns {NetworkIdT3rn}
 */
function decodeNetworkId(encodedNetworkId) {
    return Buffer.from(encodedNetworkId.slice(2), 'hex').toString('utf-8');
}
function decodeAsset(assetDecoded, destination) {
    let assetAddress = ethers_1.ethers.constants.AddressZero;
    let assetNative = true;
    try {
        assetAddress = (0, helpers_1.getAssetAddressByNumber)(destination, assetDecoded);
        const assetName = (0, helpers_1.getAssetNameByAddress)(destination, assetAddress);
        assetNative = types_1.idToNativeAssetName[destination] === assetName;
    }
    catch (error) {
        logger_1.logger.error({ error: error, assetNative, assetDecoded, assetAddress }, `🚨 Failed to decode asset`);
        return { assetNative, assetDecoded, assetAddress };
    }
    logger_1.logger.trace({ assetNative, assetDecoded, assetAddress }, `✅ Decoded asset`);
    return { assetNative, assetDecoded, assetAddress };
}
/**
 * Encodes network ID name to hex.
 * E.g. opsp --> 0x6f707374
 *
 * @param {NetworkIdT3rn}  decodedNetworkId
 * @returns {string}
 */
function encodeNetworkId(decodedNetworkId) {
    return `0x${Buffer.from(decodedNetworkId, 'utf-8').toString('hex')}`;
}
function parseAssetFromHex(asset) {
    return Number.parseInt(asset.toString(), 16);
}
function parseAssetToHex(asset) {
    return Number.parseInt(asset.toString(16));
}
/**
 * The error message used in the racePromiseWithTimeout() function.
 *
 * We need this to be declared like this, so we can reuse it in
 * conditional and validation checks in other parts of the code.
 */
exports.PromiseTimeoutErrorMsg = 'Timeout';
/**
 * Returns a promise that resolves or rejects based on the first settled promise
 * between the provided promise and a timeout.
 *
 * @template T The type of the resolved value of the input promise.
 * @param {Promise<T>} promise The promise to race against.
 * @param {number} timeoutSec  The timeout duration in seconds.
 * @returns {Promise<T>} A promise that settles based on the first settled promise
 * (either the input promise or the timeout).
 * @throws {Error} - Throws an error with the message 'Timeout' if the timeout is reached.
 */
async function racePromiseWithTimeout(promise, timeoutSec) {
    return Promise.race([
        promise,
        new Promise((_, reject) => setTimeout(() => reject(new Error(exports.PromiseTimeoutErrorMsg)), timeoutSec * 1000)),
    ]);
}
const isRemoteL3 = (networkId, config) => {
    return config.featureFlags.remoteL3AttestationBook === networkId && config.featureFlags.enableRemoteL3;
};
exports.isRemoteL3 = isRemoteL3;
const isL3 = (networkId) => {
    return networkId === 'l1rn' || networkId === 'l0rn' || networkId === 'l3rn' || networkId === 'l2rn';
};
exports.isL3 = isL3;
const isNonNativeEth = (networkId) => {
    return (0, exports.isL3)(networkId) || (0, exports.isBNB)(networkId) || (0, exports.isMonad)(networkId) || (0, exports.isSEI)(networkId);
};
exports.isNonNativeEth = isNonNativeEth;
const isBNB = (networkId) => {
    return networkId === 'bsct' || networkId === 'bscm';
};
exports.isBNB = isBNB;
const isMonad = (networkId) => {
    return networkId === 'mont' || networkId === 'monm';
};
exports.isMonad = isMonad;
const isSEI = (networkId) => {
    return networkId === 'seit' || networkId === 'seim';
};
exports.isSEI = isSEI;
const isArbitrum = (networkId) => {
    return networkId === 'arbt' || networkId === 'arbm';
};
exports.isArbitrum = isArbitrum;
const isCelestia = (networkId) => {
    return networkId === 'ctim' || networkId === 'ctit';
};
exports.isCelestia = isCelestia;
const isExoticBridgeNetworkId = (networkId) => {
    return (0, exports.isCelestia)(networkId);
};
exports.isExoticBridgeNetworkId = isExoticBridgeNetworkId;
const isRemoteL3Supported = (config) => {
    return config.featureFlags.remoteL3AttestationBook !== config.l3.currentActiveNetwork;
};
exports.isRemoteL3Supported = isRemoteL3Supported;
function initRemoteAttestationsBooks(config, nonceManager, wallet) {
    if (config.featureFlags.remoteL3AttestationBook === config.l3.currentActiveNetwork ||
        !config.featureFlags.enableRemoteL3) {
        return [{}, {}];
    }
    const remoteL3Config = config.networks[config.featureFlags.remoteL3AttestationBook];
    if (!remoteL3Config ||
        !remoteL3Config.contracts.L3.singleAttestationBookV4 ||
        !remoteL3Config.contracts.L3.longRangeAttestationsBook) {
        logger_1.logger.error(`🚨 Missing contracts for Attesting and Batching on L3 network ${config.featureFlags.remoteL3AttestationBook}`);
        return [{}, {}];
    }
    const secret = nonceManager ? nonceManager[config.featureFlags.remoteL3AttestationBook] : wallet || {};
    const singleAttestationBookContract = (0, contract_1.initContract)(contract_1.ContractName.SingleAttestationBookV4, remoteL3Config.contracts.L3.singleAttestationBookV4, secret);
    const attestationBatchMakerContract = (0, contract_1.initContract)(contract_1.ContractName.LongRangeAttestationsBook, remoteL3Config.contracts.L3.longRangeAttestationsBook, secret);
    logger_1.logger.info({ attestationBatchMakerContract: attestationBatchMakerContract.address }, `🚧 Using V4 contracts for Attesting and Batching on Remote L3 network ${config.featureFlags.remoteL3AttestationBook}`);
    return [singleAttestationBookContract, attestationBatchMakerContract];
}
/**
 * We initialize the L3 network separately and before any other networks,
 * since it will have only one instance of each (rpc, wallet, contracts) and be constant.
 */
async function initL3Network(rpc, configL3, config, prometheus, sqsDetails, appName) {
    logger_1.logger.info({ networkId: configL3.id }, `✅ L3 network initialization`);
    const rpcUrls = appName === 'messiah' && configL3.id === 'l2rn' ? ['https://b2n.rpc.caldera.xyz/http'] : configL3.rpcEndpoints;
    const provider = rpc.init(rpcUrls, configL3);
    await provider.ready;
    if (!config.privateKey) {
        logger_1.logger.error('🛑 Private key not found in config');
        throw new Error('Private key not found in config');
    }
    const wallet = new ethers_1.Wallet(config.privateKey, provider);
    const nonceManager = new experimental_1.NonceManager(wallet);
    const remoteOrderContractMap = {};
    const avpBatchSubmitterMap = {};
    const attestersContractMap = {};
    const remoteOrderContract = (0, contract_1.initContract)(contract_1.ContractName.RemoteOrder, configL3.contracts.remoteOrder, nonceManager);
    const avpBatchSubmitter = configL3.contracts.avpBatchSubmitter
        ? (0, contract_1.initContract)(contract_1.ContractName.avpBatchSubmitter, configL3.contracts.avpBatchSubmitter, nonceManager)
        : {};
    const attestersContract = (0, contract_1.initContract)(contract_1.ContractName.AttestationsVerifierProofs, configL3.contracts.attesters, nonceManager);
    remoteOrderContractMap[configL3.id] = remoteOrderContract;
    avpBatchSubmitterMap[configL3.id] = avpBatchSubmitter;
    attestersContractMap[configL3.id] = attestersContract;
    const orderBookContract = (0, contract_1.initContract)(contract_1.ContractName.OrderBook, configL3.contracts.L3.orderBook, nonceManager);
    const escrowOrderBookContract = (0, contract_1.initContract)(contract_1.ContractName.EscrowOrderBook, configL3.contracts.L3.escrowOrderBook || '', nonceManager);
    const biddingBookContract = (0, contract_1.initContract)(contract_1.ContractName.BiddingBook, configL3.contracts.L3.biddingBook, nonceManager);
    const attestersPortalContract = (0, contract_1.initContract)(contract_1.ContractName.AttestersPortal, configL3.contracts.L3.attestersPortal, nonceManager);
    const confirmationBookContract = (0, contract_1.initContract)(contract_1.ContractName.ConfirmationBook, configL3.contracts.L3.confirmationBook, nonceManager);
    let singleAttestationBookContract = (0, contract_1.initContract)(contract_1.ContractName.SingleAttestationBook, configL3.contracts.L3.singleAttestationBook, nonceManager);
    let attestationBatchMakerContract = (0, contract_1.initContract)(contract_1.ContractName.AttestationBatchMaker, configL3.contracts.L3.attestationBatchMaker, nonceManager);
    const attestationBatchMakerContractV1 = configL3.contracts.L3.attestationBatchMaker
        ? (0, contract_1.initContract)(contract_1.ContractName.AttestationBatchMaker, configL3.contracts.L3.attestationBatchMaker, nonceManager)
        : {};
    const attestationBatchMakerContractV2 = configL3.contracts.L3.attestationBatchMakerV2
        ? (0, contract_1.initContract)(contract_1.ContractName.AttestationBatchMakerV2, configL3.contracts.L3.attestationBatchMakerV2, nonceManager)
        : {};
    const attestationBatchMakerContractV3 = configL3.contracts.L3.attestationBatchMakerV3
        ? (0, contract_1.initContract)(contract_1.ContractName.AttestationBatchMakerV3, configL3.contracts.L3.attestationBatchMakerV3, nonceManager)
        : {};
    const singleAttestationBookContractV1 = configL3.contracts.L3.singleAttestationBook
        ? (0, contract_1.initContract)(contract_1.ContractName.SingleAttestationBook, configL3.contracts.L3.singleAttestationBook, nonceManager)
        : {};
    const singleAttestationBookContractV2 = configL3.contracts.L3.singleAttestationBookV2
        ? (0, contract_1.initContract)(contract_1.ContractName.SingleAttestationBookV2, configL3.contracts.L3.singleAttestationBookV2, nonceManager)
        : {};
    const singleAttestationBookContractV3 = configL3.contracts.L3.singleAttestationBookV3
        ? (0, contract_1.initContract)(contract_1.ContractName.SingleAttestationBookV3, configL3.contracts.L3.singleAttestationBookV3, nonceManager)
        : {};
    const segmentBookContract = configL3.contracts.L3.segmentBook
        ? (0, contract_1.initContract)(contract_1.ContractName.SegmentBook, configL3.contracts.L3.segmentBook, nonceManager)
        : {};
    const payloadGetterContract = configL3.contracts.L3.payloadGetter
        ? (0, contract_1.initContract)(contract_1.ContractName.PayloadGetter, configL3.contracts.L3.payloadGetter, nonceManager)
        : {};
    if (config.appName !== 'executor' || appName !== 'executor') {
        if (config.featureFlags.v3 || config.featureFlags.v4) {
            if (config.featureFlags.v4 &&
                configL3.contracts.L3.longRangeAttestationsBook &&
                configL3.contracts.L3.singleAttestationBookV4) {
                attestationBatchMakerContract = (0, contract_1.initContract)(contract_1.ContractName.LongRangeAttestationsBook, configL3.contracts.L3.longRangeAttestationsBook, nonceManager);
                singleAttestationBookContract = (0, contract_1.initContract)(contract_1.ContractName.SingleAttestationBookV4, configL3.contracts.L3.singleAttestationBookV4, nonceManager);
                logger_1.logger.debug({
                    networkId: config.l3.currentActiveNetwork,
                    singleAttestationBookContract: singleAttestationBookContract.address,
                    attestationBatchMakerContract: attestationBatchMakerContract.address,
                }, `🚧 Using V4 contracts for Attesting and Batching on L3`);
            }
            else if (config.featureFlags.v3 &&
                configL3.contracts.L3.attestationBatchMakerV3 &&
                configL3.contracts.L3.singleAttestationBookV3) {
                attestationBatchMakerContract = (0, contract_1.initContract)(contract_1.ContractName.AttestationBatchMakerV3, configL3.contracts.L3.attestationBatchMakerV3, nonceManager);
                singleAttestationBookContract = (0, contract_1.initContract)(contract_1.ContractName.SingleAttestationBookV3, configL3.contracts.L3.singleAttestationBookV3, nonceManager);
                logger_1.logger.info({ networkId: config.l3.currentActiveNetwork }, `🚧 Using V3 contracts for Attesting and Batching on L3`);
            }
        }
        else if (config.featureFlags.v2) {
            logger_1.logger.info(`🚧 Using V2 contracts for Attesting and Batching on L3`);
            if (configL3.contracts.L3.attestationBatchMakerV2 && configL3.contracts.L3.singleAttestationBookV2) {
                attestationBatchMakerContract = (0, contract_1.initContract)(contract_1.ContractName.AttestationBatchMakerV2, configL3.contracts.L3.attestationBatchMakerV2, nonceManager);
                singleAttestationBookContract = (0, contract_1.initContract)(contract_1.ContractName.SingleAttestationBookV2, configL3.contracts.L3.singleAttestationBookV2, nonceManager);
            }
        }
    }
    const bonusesL3 = configL3.contracts.L3.bonusesL3
        ? (0, contract_1.initContract)(contract_1.ContractName.BonusesL3, configL3.contracts.L3.bonusesL3, nonceManager)
        : {};
    const BRNRewardsContract = (0, contract_1.initContract)(contract_1.ContractName.BRNRewards, configL3.contracts.L3.BRNRewards, nonceManager);
    const BRNBalanceGetterContract = configL3.contracts.L3.BRNBalanceGetter
        ? (0, contract_1.initContract)(contract_1.ContractName.BRNBalanceGetter, configL3.contracts.L3.BRNBalanceGetter, nonceManager)
        : {};
    const transmitter = new transmitter_service_1.Transmitter(config, nonceManager, prometheus, provider, configL3.id, configL3.name, sqsDetails);
    transmitter.init(remoteOrderContractMap, attestersContractMap, attestersPortalContract, orderBookContract, escrowOrderBookContract, biddingBookContract, confirmationBookContract, singleAttestationBookContract, attestationBatchMakerContract, bonusesL3, payloadGetterContract, avpBatchSubmitterMap, segmentBookContract);
    let insurance = ethers_1.BigNumber.from('0');
    try {
        insurance = await orderBookContract.getCurrentInsuranceInNative();
        logger_1.logger.debug({ insurance: insurance.toString() }, `🏦 Current insurance on L3 network`);
    }
    catch (error) {
        const err = (0, error_1.extractErrorDetails)(error);
        logger_1.logger.error({ code: err.code, error: err.message }, `🚨 Failed to get current insurance from OrderBook contract. Return zero.`);
    }
    let supportRevertCommitments = false;
    if (config.featureFlags.supportRevertCommitments) {
        try {
            supportRevertCommitments = await attestersContract.skipEscrowWrites();
            logger_1.logger.debug({ supportRevertCommitments }, `🏦 Support for revert commitments on L3 network`);
        }
        catch (_err) {
            const err = (0, error_1.extractErrorDetails)(_err);
            logger_1.logger.error({ code: err.code, error: err.message }, `🚨 Failed to get support for revert commitments from AttestersVerifierProofs contract. Return false.`);
        }
    }
    return {
        provider,
        wallet,
        nonceManager,
        orderBookContract,
        escrowOrderBookContract,
        biddingBookContract,
        attestersPortalContract,
        segmentBookContract,
        singleAttestationBookContract,
        attestationBatchMakerContract,
        attestationBatchMakerContractV1,
        attestationBatchMakerContractV2,
        attestationBatchMakerContractV3,
        singleAttestationBookContractV1,
        singleAttestationBookContractV2,
        singleAttestationBookContractV3,
        confirmationBookContract,
        BRNRewardsContract,
        BRNBalanceGetterContract,
        payloadGetterContract,
        bonusesL3,
        transmitter,
        insurance,
        supportRevertCommitments,
    };
}
/**
 * Waits for all transmitters to complete processing their queues and dry out.
 * This is used during gracefully shutting down services.
 *
 * @param transmittersMap
 * @param config
 */
async function waitTransmitterFinishProcessing(transmittersMap, config) {
    const waitStartAt = Date.now();
    let anyTransmitterIsProcessing = true;
    const enabledTransmittersCount = transmittersMap.size;
    while (anyTransmitterIsProcessing) {
        let stoppedTransmittersCount = 0;
        for (const transmitter of transmittersMap.values()) {
            if (transmitter.areQueuesEmpty()) {
                stoppedTransmittersCount++;
            }
        }
        if (stoppedTransmittersCount === enabledTransmittersCount) {
            anyTransmitterIsProcessing = false;
        }
        else {
            if (waitStartAt + config.shutdown.waitMaxSec * 1000 <= Date.now()) {
                logger_1.logger.info(`Max shutdown wait time of ${config.shutdown.waitMaxSec} secs reached. Exit forcefully.`);
                return;
            }
            const secsMoreToWait = Math.ceil(config.shutdown.waitMaxSec - (Date.now() - waitStartAt) / 1000);
            logger_1.logger.info(`There are still txs in progress! Waiting for ${secsMoreToWait} sec more...`);
            await sleep(config.shutdown.waitBetweenRetriesSec, 'Waiting before checking if transmitters still processing txs');
        }
    }
}
async function setInfiniteAllowanceOnAssetForAddress(networkId, assetId, wallet, targetAddress, rpcProvider, childLogger) {
    let assetAddress;
    try {
        assetAddress = (0, helpers_1.getAssetAddressByNumber)(networkId, assetId, 'setInfiniteAllowanceOnAssetForAddress');
        if (assetAddress == ethers_1.ethers.constants.AddressZero) {
            return false;
        }
    }
    catch (error) {
        const err = (0, error_1.extractErrorDetails)(error);
        childLogger.warn({
            assetId,
            error: err.message,
        }, `🟡 Allowance:: AssetAddress for asset not found. Skip.`);
        return false;
    }
    const isNetworkParachain = networkId === 't1rn' || networkId === 't2rn' || networkId === 't3rn';
    let assetContract;
    try {
        assetContract = !isNetworkParachain
            ? (0, contract_1.initContract)(contract_1.ContractName.ERC20Mock, assetAddress, wallet)
            : (0, contract_1.initContract)(contract_1.ContractName.tERC20, assetAddress, wallet);
        const allowance = await assetContract.allowance(wallet.address, targetAddress);
        if (allowance > ethers_1.BigNumber.from(0)) {
            childLogger.debug({
                assetId,
                assetAddress,
                allowance: allowance.toString(),
            }, `✅ Allowance:: Infinite allowance already set`);
            return true;
        }
    }
    catch (error) {
        const err = (0, error_1.shallowExtractErrorDetails)(error);
        childLogger.error({
            assetId,
            assetAddress,
            code: err.code,
            error: err.message,
        }, `🚨 Allowance:: Failed to get current allowance. Skip.`);
        return false;
    }
    try {
        const txParams = rpcProvider.estimateGasParams();
        const tx = await assetContract.approve(targetAddress, ethers_1.ethers.constants.MaxUint256, {
            ...txParams,
        });
        childLogger.info({
            assetId,
            assetAddress,
            tx: (0, flatted_1.stringify)(tx),
        }, `✅ Allowance:: Infinite allowance set`);
    }
    catch (error) {
        const err = (0, error_1.shallowExtractErrorDetails)(error);
        childLogger.error({
            assetId,
            assetAddress,
            code: err.code,
            error: err.message,
        }, `🚨 Allowance:: Failed to set infinite allowance`);
        return false;
    }
    return true;
}
function shouldTrackLifecycleEvent(event) {
    const ignoreList = new Set([
        'LateOrderDLQL3',
        'BatchPopulateL3',
        'RemoveGMPUnmatched',
        'TryConstructBatchL3',
        'AnchorEscrowGMPPayloadUnmatchedToL3',
    ]);
    return !ignoreList.has(event);
}
function restoreBigNumbers(data) {
    if (data && typeof data === 'object') {
        if (data.type === 'BigNumber' && data.hex) {
            return ethers_1.BigNumber.from(data.hex);
        }
        if (Array.isArray(data)) {
            return data.map((element) => restoreBigNumbers(element));
        }
        const newData = {};
        for (const key in data) {
            const value = data[key];
            newData[key] = restoreBigNumbers(value); // recursively process nested objects
        }
        return newData;
    }
    return data; // return primitive values as is
}
function generateOrderId(networkId, addr, nonce) {
    const encodedEncodedNetworkId = encodeNetworkId(networkId);
    const xtx_id = ethers_1.ethers.utils.keccak256(ethers_1.ethers.utils.defaultAbiCoder.encode(['address', 'uint32', 'bytes4'], [addr, nonce, encodedEncodedNetworkId]));
    return ethers_1.ethers.utils.keccak256(ethers_1.ethers.utils.defaultAbiCoder.encode(['bytes32', 'bytes32'], [xtx_id, '0x0000000000000000000000000000000000000000000000000000000000000000']));
}
/**
 * This function crafts the calldata to be passed for escrow calls
 * @param orderType - The type of order
 * @param data - The encoded order details in bytes
 * @returns the encoded orderDetails
 */
function createOrderDetails(orderType, data) {
    return ethers_1.ethers.utils.defaultAbiCoder.encode(['tuple(uint8 orderType, bytes data)'], [[orderType, data]]);
}
/**
 * This function encodes the ERC20 order details
 * @param tokenToReceive - The address of the token to receive
 * @param minAmount - The minimum amount of tokens to receive
 * @param destinationAccount - The address of the destination account
 * @returns the encoded ERC20 order details
 */
function encodeERC20Order(tokenToReceive, minAmount, destinationAccount) {
    return ethers_1.ethers.utils.defaultAbiCoder.encode(['address', 'uint256', 'bytes32'], [tokenToReceive, minAmount, destinationAccount]);
}
/**
 * This function encodes the ERC721 mint order details
 * @param nftAddress - The address of the NFT contract
 * @param mintQuantity - The quantity of NFTs to mint
 * @param destinationAccount - The address of the destination account
 * @returns the encoded ERC721 mint order details
 */
function encodeERC721MintOrder(nftAddress, mintQuantity, destinationAccount) {
    return ethers_1.ethers.utils.defaultAbiCoder.encode(['address', 'uint256', 'bytes32'], [nftAddress, mintQuantity, destinationAccount]);
}
function fetchEnvVarOrThrow(name) {
    const value = process.env[name];
    if (!value) {
        throw new Error(`Environment variable ${name} is not set`);
    }
    return value;
}
// Mimics generateId of contract
function generateIdFull(requester, nonce, networkId) {
    try {
        return ethers_1.ethers.utils.keccak256(ethers_1.ethers.utils.defaultAbiCoder.encode(['bytes32', 'bytes32'], [
            ethers_1.ethers.utils.keccak256(ethers_1.ethers.utils.defaultAbiCoder.encode(['address', 'uint32', 'bytes4'], [requester, nonce, networkId])),
            ethers_1.ethers.constants.HashZero,
        ]));
    }
    catch (error) {
        logger_1.logger.error({ error: error.message, requester, nonce, networkId }, `🚚↩️ Error while generateIdFull order ID`);
        return ethers_1.ethers.constants.HashZero;
    }
}
//# sourceMappingURL=helpers.js.map