import { isSolanaLike as e } from "../../constants/chains.constants.mjs";
import { CIRCOM_P as t } from "../../constants/protocol.constants.mjs";
import { poseidonHash as n } from "../../crypto/poseidon.mjs";
import { randomBigInt as r } from "../../functions/web3/etherFunctions.mjs";
import { UserKeys as i } from "../crypto-keys/keys.mjs";
import { getCurrentTimeInSeconds as a } from "../../functions/utils/time.utils.mjs";
//#region libs/shared/common/src/data-structures/utxo/Utxo.ts
var o = class o {
	amount;
	erc20TokenAddress;
	mintAddress;
	timeStamp;
	tokenId;
	shieldedPrivateKey;
	randomization;
	stealthAddress;
	encryptionKey;
	commitment;
	nullifier;
	isBlocked;
	constructor({ amount: e, erc20TokenAddress: t, mintAddress: n, timeStamp: i, tokenId: s, shieldedPrivateKey: c, randomization: l, stealthAddress: u, encryptionKey: d, commitment: f = void 0, nullifier: p = void 0, isBlocked: m = !1 }) {
		this.amount = e, this.erc20TokenAddress = t, this.mintAddress = n, this.timeStamp = i ?? a().toString(), this.tokenId = s ?? 0, this.shieldedPrivateKey = c, this.randomization = l ?? o.findCorrectRandomization(r(31), c), this.stealthAddress = u, this.encryptionKey = d, this.commitment = f, this.nullifier = p, this.isBlocked = m;
	}
	static createFrom(e, t) {
		return new o({
			...e.getConstructableParams(),
			nullifier: void 0,
			commitment: void 0,
			...t
		});
	}
	getConstructableParams() {
		return {
			amount: this.amount,
			erc20TokenAddress: this.erc20TokenAddress,
			mintAddress: this.mintAddress,
			timeStamp: this.timeStamp,
			shieldedPrivateKey: this.shieldedPrivateKey,
			randomization: this.randomization,
			stealthAddress: this.stealthAddress,
			encryptionKey: this.encryptionKey,
			tokenId: this.tokenId,
			commitment: this.commitment,
			nullifier: this.nullifier,
			isBlocked: this.isBlocked
		};
	}
	getBasicUtxoParams() {
		return {
			amount: this.amount,
			erc20TokenAddress: this.erc20TokenAddress,
			mintAddress: this.mintAddress,
			timeStamp: this.timeStamp,
			randomization: this.randomization,
			stealthAddress: this.stealthAddress,
			tokenId: this.tokenId,
			commitment: this.commitment,
			nullifier: this.nullifier,
			isBlocked: this.isBlocked
		};
	}
	getCommitment() {
		if (!this.commitment) {
			let e = [
				this.amount,
				this.erc20TokenAddress,
				BigInt(this.getStealthAddress()),
				this.timeStamp
			];
			this.tokenId > 0 && e.push(this.tokenId.toString()), this.commitment = n(...e);
		}
		return this.commitment;
	}
	getNullifier() {
		if (!this.nullifier) {
			if (!this.shieldedPrivateKey) throw Error("No Nullifiers if private key is not provided");
			let e = n(this.shieldedPrivateKey, this.getCommitment());
			this.nullifier = n(this.commitment, e);
		}
		return this.nullifier;
	}
	getStealthAddress() {
		if (!this.stealthAddress) {
			if (!this.shieldedPrivateKey) throw Error("No stealth address in UTXO if private key is not provided");
			let e = i.getStealthAddress(this.randomization, this.shieldedPrivateKey);
			this.stealthAddress = e;
		}
		return this.stealthAddress;
	}
	getEncryptionKey() {
		if (!this.shieldedPrivateKey) {
			if (!this.encryptionKey) throw Error("No encryption key provided in UTXO");
			return this.encryptionKey;
		}
		return i.getEncryptionKeyPair(this.shieldedPrivateKey).publicKey;
	}
	static findCorrectRandomization(e, n) {
		if (!n) throw Error("No Private Shielded Key Provided");
		let r = BigInt(n) % t, i, a, o = 0n;
		do
			i = e * 10n ** o % t, a = i * r % t, o += 1n;
		while (a >= 2n ** 253n || i >= 2n ** 253n);
		return i;
	}
	getTokenAddress(t) {
		let n = e(t) ? this.mintAddress : this.erc20TokenAddress;
		if (!n) throw Error("No token address provided");
		return n;
	}
};
//#endregion
export { o as Utxo };
