"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Signer = exports.keccak256 = exports.defaultAbiCoder = exports.BigNumber = exports.ethers = exports.Contract = exports.isBytes32 = exports.bytes32ToAddress = exports.addressToBytes = exports.hexZeroPad = exports.createRandomBytes32 = exports.hexToUtf8 = exports.utf8ToHex = exports.toBN = exports.fromWei = exports.toBNWeiWithDecimals = exports.toBNWei = exports.toWeiWithDecimals = exports.toWei = void 0;
exports.findArtifactFromPath = findArtifactFromPath;
exports.getAllFilesInPath = getAllFilesInPath;
exports.seedWallet = seedWallet;
exports.seedContract = seedContract;
exports.randomBigNumber = randomBigNumber;
exports.randomAddress = randomAddress;
exports.randomBytes32 = randomBytes32;
exports.trimSolanaAddress = trimSolanaAddress;
exports.hashNonEmptyMessage = hashNonEmptyMessage;
exports.avmL1ToL2Alias = avmL1ToL2Alias;
exports.getOftEid = getOftEid;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const ethers_1 = require("ethers");
Object.defineProperty(exports, "ethers", { enumerable: true, get: function () { return ethers_1.ethers; } });
const ethers_2 = require("ethers");
Object.defineProperty(exports, "BigNumber", { enumerable: true, get: function () { return ethers_2.BigNumber; } });
Object.defineProperty(exports, "Signer", { enumerable: true, get: function () { return ethers_2.Signer; } });
Object.defineProperty(exports, "Contract", { enumerable: true, get: function () { return ethers_2.Contract; } });
const consts_1 = require("../src/consts");
function findArtifactFromPath(contractName, artifactsPath) {
    const allArtifactsPaths = getAllFilesInPath(artifactsPath);
    const desiredArtifactPaths = allArtifactsPaths.filter((a) => a.endsWith(`/${contractName}.json`));
    if (desiredArtifactPaths.length !== 1)
        throw new Error(`Couldn't find desired artifact or found too many for ${contractName}`);
    return JSON.parse(fs_1.default.readFileSync(desiredArtifactPaths[0], "utf-8"));
}
function getAllFilesInPath(dirPath, arrayOfFiles = []) {
    const files = fs_1.default.readdirSync(dirPath);
    files.forEach((file) => {
        if (fs_1.default.statSync(dirPath + "/" + file).isDirectory())
            arrayOfFiles = getAllFilesInPath(dirPath + "/" + file, arrayOfFiles);
        else
            arrayOfFiles.push(path_1.default.join(dirPath, "/", file));
    });
    return arrayOfFiles;
}
const toWei = (num) => ethers_1.ethers.utils.parseEther(num.toString());
exports.toWei = toWei;
const toWeiWithDecimals = (num, decimals) => ethers_1.ethers.utils.parseUnits(num.toString(), decimals);
exports.toWeiWithDecimals = toWeiWithDecimals;
const toBNWei = (num) => ethers_2.BigNumber.from((0, exports.toWei)(num));
exports.toBNWei = toBNWei;
const toBNWeiWithDecimals = (num, decimals) => ethers_2.BigNumber.from((0, exports.toWeiWithDecimals)(num, decimals));
exports.toBNWeiWithDecimals = toBNWeiWithDecimals;
const fromWei = (num) => ethers_1.ethers.utils.formatUnits(num.toString());
exports.fromWei = fromWei;
const toBN = (num) => {
    // If the string version of the num contains a `.` then it is a number which needs to be parsed to a string int.
    if (num.toString().includes("."))
        return ethers_2.BigNumber.from(parseInt(num.toString()));
    return ethers_2.BigNumber.from(num.toString());
};
exports.toBN = toBN;
const utf8ToHex = (input) => ethers_1.ethers.utils.formatBytes32String(input);
exports.utf8ToHex = utf8ToHex;
const hexToUtf8 = (input) => ethers_1.ethers.utils.toUtf8String(input);
exports.hexToUtf8 = hexToUtf8;
const createRandomBytes32 = () => ethers_1.ethers.utils.hexlify(ethers_1.ethers.utils.randomBytes(32));
exports.createRandomBytes32 = createRandomBytes32;
const hexZeroPad = (input, length) => ethers_1.ethers.utils.hexZeroPad(input, length);
exports.hexZeroPad = hexZeroPad;
const addressToBytes = (input) => (0, exports.hexZeroPad)(input.toLowerCase(), 32);
exports.addressToBytes = addressToBytes;
const bytes32ToAddress = (input) => {
    if (!/^0x[a-fA-F0-9]{64}$/.test(input)) {
        throw new Error("Invalid bytes32 input");
    }
    return ethers_1.ethers.utils.getAddress("0x" + input.slice(26));
};
exports.bytes32ToAddress = bytes32ToAddress;
const isBytes32 = (input) => /^0x[0-9a-fA-F]{64}$/.test(input);
exports.isBytes32 = isBytes32;
async function seedWallet(walletToFund, tokens, weth, amountToSeedWith) {
    for (const token of tokens)
        await token.mint(await walletToFund.getAddress(), amountToSeedWith);
    if (weth)
        await weth.connect(walletToFund).deposit({ value: amountToSeedWith });
}
async function seedContract(contract, walletToFund, tokens, weth, amountToSeedWith) {
    await seedWallet(walletToFund, tokens, weth, amountToSeedWith);
    for (const token of tokens)
        await token.connect(walletToFund).transfer(contract.address, amountToSeedWith);
    if (weth)
        await weth.connect(walletToFund).transfer(contract.address, amountToSeedWith);
}
function randomBigNumber(bytes = 32, signed = false) {
    const sign = signed && Math.random() < 0.5 ? "-" : "";
    const byteString = "0x" + Buffer.from(ethers_1.ethers.utils.randomBytes(signed ? bytes - 1 : bytes)).toString("hex");
    return ethers_1.ethers.BigNumber.from(sign + byteString);
}
function randomAddress() {
    return ethers_1.ethers.utils.getAddress(ethers_1.ethers.utils.hexlify(ethers_1.ethers.utils.randomBytes(20)));
}
function randomBytes32() {
    return ethers_1.ethers.utils.hexlify(ethers_1.ethers.utils.randomBytes(32));
}
function avmL1ToL2Alias(l1Address) {
    const offset = (0, exports.toBN)("0x1111000000000000000000000000000000001111");
    const l1AddressAsNumber = (0, exports.toBN)(l1Address);
    const l2AddressAsNumber = l1AddressAsNumber.add(offset);
    const mask = (0, exports.toBN)("2").pow((0, exports.toBN)("160"));
    return ethers_1.ethers.utils.hexlify(l2AddressAsNumber.mod(mask));
}
function trimSolanaAddress(bytes32Address) {
    if (!ethers_1.ethers.utils.isHexString(bytes32Address, 32)) {
        throw new Error("Invalid bytes32 address");
    }
    const uint160Address = ethers_1.ethers.BigNumber.from(bytes32Address).mask(160);
    return ethers_1.ethers.utils.hexZeroPad(ethers_1.ethers.utils.hexlify(uint160Address), 20);
}
function hashNonEmptyMessage(message) {
    if (!ethers_1.ethers.utils.isHexString(message) || message.length % 2 !== 0)
        throw new Error("Invalid hex message bytes");
    // account for 0x prefix when checking length
    if (message.length > 2) {
        return ethers_1.ethers.utils.keccak256(message);
    }
    return ethers_1.ethers.utils.hexlify(new Uint8Array(32));
}
const { defaultAbiCoder, keccak256 } = ethers_1.ethers.utils;
exports.defaultAbiCoder = defaultAbiCoder;
exports.keccak256 = keccak256;
function getOftEid(chainId) {
    const value = consts_1.OFT_EIDs.get(chainId);
    if (value === undefined) {
        throw new Error(`Chain id ${chainId} not present in OFT_EIDs`);
    }
    return value;
}
