"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.addressOrBase58ToBytes32 = exports.fromBytes32ToAddress = exports.fromBase58ToBytes32 = exports.publicKeyToEvmAddress = exports.evmAddressToPublicKey = void 0;
exports.intToU8Array32 = intToU8Array32;
exports.u8Array32ToInt = u8Array32ToInt;
exports.u8Array32ToBigNumber = u8Array32ToBigNumber;
exports.strPublicKey = strPublicKey;
const anchor_1 = require("@coral-xyz/anchor");
const web3_js_1 = require("@solana/web3.js");
const ethers_1 = require("ethers");
/**
 * Converts an integer to a 32-byte Uint8Array.
 */
function intToU8Array32(num) {
    const bigIntValue = BigInt(num instanceof anchor_1.BN ? num.toString() : num);
    if (bigIntValue < 0)
        throw new Error("Input must be a non-negative integer or BN");
    const hexString = bigIntValue.toString(16).padStart(64, "0"); // 32 bytes = 64 hex chars
    const u8Array = Array.from(Buffer.from(hexString, "hex"));
    return u8Array;
}
/**
 * Converts a 32-byte Uint8Array to a bigint.
 */
function u8Array32ToInt(u8Array) {
    const isValidArray = (arr) => Array.isArray(arr) && arr.every(Number.isInteger);
    if ((u8Array instanceof Uint8Array || isValidArray(u8Array)) && u8Array.length === 32) {
        return Array.from(u8Array).reduce((num, byte) => (num << 8n) | BigInt(byte), 0n);
    }
    throw new Error("Input must be a Uint8Array or an array of 32 numbers.");
}
/**
 * Converts a 32-byte Uint8Array to a BigNumber.
 */
function u8Array32ToBigNumber(u8Array) {
    const isValidArray = (arr) => Array.isArray(arr) && arr.every(Number.isInteger);
    if ((u8Array instanceof Uint8Array || isValidArray(u8Array)) && u8Array.length === 32) {
        const hexString = "0x" + Buffer.from(u8Array).toString("hex");
        return ethers_1.BigNumber.from(hexString);
    }
    throw new Error("Input must be a Uint8Array or an array of 32 numbers.");
}
/**
 * Converts a string to a PublicKey.
 */
function strPublicKey(publicKey) {
    return new web3_js_1.PublicKey(publicKey).toString();
}
/**
 * Converts an EVM address to a Solana PublicKey.
 */
const evmAddressToPublicKey = (address) => {
    const bytes32Address = `0x000000000000000000000000${address.replace("0x", "")}`;
    return new web3_js_1.PublicKey(ethers_1.ethers.utils.arrayify(bytes32Address));
};
exports.evmAddressToPublicKey = evmAddressToPublicKey;
/**
 * Converts a Solana PublicKey to an EVM address.
 */
const publicKeyToEvmAddress = (publicKey) => {
    // Convert the input to a PublicKey if it's a string
    const pubKeyBuffer = typeof publicKey === "string" ? new web3_js_1.PublicKey(publicKey).toBuffer() : publicKey.toBuffer();
    // Extract the last 20 bytes to get the Ethereum address
    const addressBuffer = pubKeyBuffer.slice(-20);
    // Convert the buffer to a hex string and prepend '0x'
    return `0x${addressBuffer.toString("hex")}`;
};
exports.publicKeyToEvmAddress = publicKeyToEvmAddress;
/**
 * Converts a base58 string to a bytes32 string.
 */
const fromBase58ToBytes32 = (input) => {
    const decodedBytes = anchor_1.utils.bytes.bs58.decode(input);
    return "0x" + Buffer.from(decodedBytes).toString("hex");
};
exports.fromBase58ToBytes32 = fromBase58ToBytes32;
/**
 * Converts a bytes32 string to an EVM address.
 */
const fromBytes32ToAddress = (input) => {
    const hexString = input.startsWith("0x") ? input.slice(2) : input;
    if (hexString.length !== 64) {
        throw new Error("Invalid bytes32 string");
    }
    const address = hexString.slice(-40);
    return "0x" + address;
};
exports.fromBytes32ToAddress = fromBytes32ToAddress;
/**
 * Converts EVM or SVM address to a bytes32 string.
 */
const addressOrBase58ToBytes32 = (input) => {
    if (ethers_1.ethers.utils.isAddress(input)) {
        return ethers_1.ethers.utils.hexZeroPad(input, 32);
    }
    else if (ethers_1.ethers.utils.isHexString(input, 32)) {
        return input;
    }
    else {
        return (0, exports.fromBase58ToBytes32)(input);
    }
};
exports.addressOrBase58ToBytes32 = addressOrBase58ToBytes32;
