"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getDeployedContractAddressFromContractReceipt = exports.getBlockTimestamp = exports.unlinkFile = exports.cleanThreads = exports.isArm = exports.transferOwnership = exports.getFeeData = exports.getSigners = exports.getDefaultNetwork = exports.getDefaultSigner = exports.sleep = exports.formatProofForVerifierContract = void 0;
exports.sortActions = sortActions;
exports.asHex = asHex;
exports.generateMerkleTree = generateMerkleTree;
const merkle_tree_1 = require("@openzeppelin/merkle-tree");
const ethers_1 = require("ethers");
const fs_1 = __importDefault(require("fs"));
const os_1 = __importDefault(require("os"));
const logger_1 = require("./logger");
const IFACE_CONTRACT_CREATION = new ethers_1.Interface(["event ContractCreation(address indexed newContract)"]);
/**
 * Format a SnarkProof type to an array of strings
 * which can be passed to the Groth16 verifier contract.
 * @param proof the SnarkProof to format
 * @returns an array of strings
 */
const formatProofForVerifierContract = (proof) => [
    proof.pi_a[0],
    proof.pi_a[1],
    proof.pi_b[0][1],
    proof.pi_b[0][0],
    proof.pi_b[1][1],
    proof.pi_b[1][0],
    proof.pi_c[0],
    proof.pi_c[1],
].map((x) => x.toString());
exports.formatProofForVerifierContract = formatProofForVerifierContract;
/**
 * Pause the thread for n milliseconds
 * @param ms - the amount of time to sleep in milliseconds
 */
const sleep = async (ms) => {
    await new Promise((resolve) => {
        setTimeout(resolve, ms);
    });
};
exports.sleep = sleep;
/**
 * The comparison function for Actions based on block number and transaction
 * index.
 * @param actions - the array of actions to sort
 * @returns the sorted array of actions
 */
function sortActions(actions) {
    return actions.slice().sort((a, b) => {
        if (a.blockNumber > b.blockNumber) {
            return 1;
        }
        if (a.blockNumber < b.blockNumber) {
            return -1;
        }
        if (a.transactionIndex > b.transactionIndex) {
            return 1;
        }
        if (a.transactionIndex < b.transactionIndex) {
            return -1;
        }
        return 0;
    });
}
/**
 * Get the default signer from the hardhat node
 * @returns the default signer
 */
const getDefaultSigner = async () => {
    const { ethers } = await Promise.resolve().then(() => __importStar(require("hardhat")));
    const [signer] = await ethers.getSigners();
    return signer;
};
exports.getDefaultSigner = getDefaultSigner;
/**
 * Get the default signer network from the hardhat node
 * @returns the default network
 */
const getDefaultNetwork = async () => {
    const signer = await (0, exports.getDefaultSigner)();
    return signer.provider?.getNetwork();
};
exports.getDefaultNetwork = getDefaultNetwork;
/**
 * Get all of the available signers from the hardhat node
 * @dev to be used while testing
 * @returns the signers
 */
const getSigners = async () => {
    const { ethers } = await Promise.resolve().then(() => __importStar(require("hardhat")));
    return ethers.getSigners();
};
exports.getSigners = getSigners;
/**
 * Get the current fee data from the blockchain node.
 * This is needed to ensure transaction go through in busy times
 * @returns - the fee data
 */
const getFeeData = async () => {
    const signer = await (0, exports.getDefaultSigner)();
    return signer.provider?.getFeeData();
};
exports.getFeeData = getFeeData;
/**
 * Transfer ownership of a contract (using Ownable from OpenZeppelin)
 * @param contract - the contract to transfer ownership of
 * @param newOwner - the address of the new owner
 * @param quiet - whether to suppress console output
 */
const transferOwnership = async (contract, newOwner, quiet = false) => {
    (0, logger_1.logGreen)({ text: (0, logger_1.info)(`Transferring ownership of ${await contract.getAddress()} to ${newOwner}`), quiet });
    const tx = await contract.transferOwnership(newOwner, {
        maxFeePerGas: await (0, exports.getFeeData)().then((res) => res?.maxFeePerGas),
    });
    await tx.wait();
};
exports.transferOwnership = transferOwnership;
/**
 * Convert bignumberish to hex
 *
 * @param value - bignumberish string
 * @returns hex representation of it
 */
function asHex(value) {
    return `0x${BigInt(value).toString(16)}`;
}
function generateMerkleTree(elements) {
    return merkle_tree_1.StandardMerkleTree.of(elements, ["address"]);
}
/**
 * Check if we are running on an arm chip
 * @returns whether we are running on an arm chip
 */
const isArm = () => os_1.default.arch().includes("arm");
exports.isArm = isArm;
/*
 * https://github.com/iden3/snarkjs/issues/152
 * Need to cleanup the threads to avoid stalling
 */
const cleanThreads = async () => {
    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
    if (!globalThis) {
        return;
    }
    const curves = ["curve_bn128", "curve_bls12381"];
    await Promise.all(curves.map((curve) => globalThis[curve]?.terminate()).filter(Boolean));
};
exports.cleanThreads = cleanThreads;
/**
 * Remove a file
 * @param filepath - the path to the file
 */
const unlinkFile = async (filepath) => {
    const isFileExists = fs_1.default.existsSync(filepath);
    if (isFileExists) {
        await fs_1.default.promises.unlink(filepath);
    }
};
exports.unlinkFile = unlinkFile;
/**
 * Get the timestamp of the current block
 * @param signer - the signer to use
 * @returns the start time of the current block or the current time
 */
const getBlockTimestamp = async (signer) => {
    const block = await signer.provider?.getBlock("latest");
    return block?.timestamp ?? Math.floor(Date.now() / 1000);
};
exports.getBlockTimestamp = getBlockTimestamp;
/**
 * Get the address of the deployed contract from the transaction receipt
 * This is useful for contracts that are deployed using the CREATE2 opcode
 * or for contracts that emit a ContractCreation event. Useful for Account Abstraction txs
 * @param receipt - the transaction receipt of the contract creation
 * @returns - the address of the deployed contract
 */
const getDeployedContractAddressFromContractReceipt = (receipt) => {
    if (!receipt) {
        return undefined;
    }
    const contractCreationLog = receipt.logs.find((log) => {
        try {
            const parsedLog = IFACE_CONTRACT_CREATION.parseLog(log);
            return parsedLog?.name === "ContractCreation";
        }
        catch (err) {
            // If parseLog fails, this log is not from the ABI
            return false;
        }
    });
    return contractCreationLog ? IFACE_CONTRACT_CREATION.parseLog(contractCreationLog)?.args[0] : undefined;
};
exports.getDeployedContractAddressFromContractReceipt = getDeployedContractAddressFromContractReceipt;
//# sourceMappingURL=utils.js.map