import { CIRCOM_P as e } from "../../constants/protocol.constants.mjs";
import { poseidonHash as t } from "../../crypto/poseidon.mjs";
import { babyJubInstance as n } from "../../crypto/babyJub.mjs";
import { eddsaInstance as r } from "../../crypto/eddsa.mjs";
import { AttachableMemoryCacheDevice as i } from "../cacheDevices/AttachableMemoryCacheDevice.mjs";
import { getCircomSign as a } from "./keyUtils.mjs";
import { ethers as o } from "ethers";
import { Keypair as s, PublicKey as c } from "@solana/web3.js";
import { Trx as l } from "tronweb";
import u from "libsodium-wrappers";
import d from "bs58";
import f from "tweetnacl";
//#region libs/shared/common/src/data-structures/crypto-keys/keys.ts
var p = new i(), m = new i(), h = new i(), g = {
	privateKey: "",
	publicKey: ""
}, _ = class {
	signature;
	nullifyingKey;
	PREFIX_FOR_SPENDING_PAIR = "1";
	PREFIX_FOR_NULLIFYING_PAIR = "2";
	constructor(e, t) {
		this.signature = e, this.nullifyingKey = t;
	}
	getSignature() {
		return this.requireSignature(), this.signature;
	}
	setSignature(e) {
		this.signature = e;
	}
	requireSignature() {
		if (!this.signature) throw Error("No signature provided");
	}
	requireKeyMaterial() {
		if (!this.signature && !this.nullifyingKey) throw Error("No signature or private key provided");
	}
	verifyTronMessage(e, t) {
		return this.requireSignature(), t === l.verifyMessageV2(e, this.signature);
	}
	getShieldedPrivateKey = () => (this.requireKeyMaterial(), this.nullifyingKey ||= o.keccak256(this.signature), this.nullifyingKey);
	getShieldedPublicKey = () => (this.requireKeyMaterial(), t(this.getShieldedPrivateKey()));
	getSpendingKeyPair = () => {
		this.requireSignature();
		let e = r(), i = n(), a = t(this.PREFIX_FOR_SPENDING_PAIR, this.getSignature()), s = Buffer.from(o.getBytes(a)), c = e.prv2pub(s);
		return {
			privSpendingKey: a,
			pubSpendingBJJPoint: [BigInt(i.F.toString(c[0])), BigInt(i.F.toString(c[1]))]
		};
	};
	signEddsa = (e) => {
		this.requireSignature();
		let t = n(), i = r(), a = Buffer.from(o.getBytes(this.getSpendingKeyPair().privSpendingKey)), s = t.F.e(e), c = i.signPoseidon(a, s);
		return {
			R8: [BigInt(t.F.toString(c.R8[0])), BigInt(t.F.toString(c.R8[1]))],
			S: BigInt(c.S)
		};
	};
	getShieldedPrivateKeyFromNonce = (e) => {
		this.requireKeyMaterial();
		let n = t(e, this.getShieldedPrivateKey(), this.getShieldedPublicKey());
		return o.keccak256(o.toUtf8Bytes(`hinkal-offchain-shielded-key:${n}`));
	};
	getClaimableSignatureFromNonce = (e) => {
		this.requireKeyMaterial();
		let n = t(e, this.getShieldedPrivateKey(), this.getShieldedPublicKey());
		return o.keccak256(o.toUtf8Bytes(`hinkal-claimable-utxo-signature:${n}`));
	};
	getDerivedEthereumAddress = () => (this.requireKeyMaterial(), new o.Wallet(this.getShieldedPrivateKey()).address);
	getDerivedSolanaPublicKey = () => (this.requireKeyMaterial(), s.fromSeed(o.getBytes(this.getShieldedPrivateKey())).publicKey.toBase58());
	getSignerPrivateKeyFromNonce = (e) => {
		this.requireKeyMaterial();
		let n = t(e, this.getShieldedPrivateKey(), this.getShieldedPublicKey());
		return o.keccak256(o.toUtf8Bytes(n));
	};
	getSignerSolanaPrivateKeyFromNonce = (e) => {
		let t = this.getSignerPrivateKeyFromNonce(e), n = o.getBytes(t), r = s.fromSeed(n);
		return d.encode(r.secretKey);
	};
	verifyMessage(e) {
		return this.requireSignature(), o.verifyMessage(e, this.signature);
	}
	verifySolanaMessage(e, t) {
		this.requireSignature();
		let n = new TextEncoder().encode(e), r = o.getBytes(this.signature), i = new c(t).toBytes();
		return f.sign.detached.verify(n, r, i);
	}
	static getRandomizedStealthPairOld = m.attach((t, r) => {
		let i = n(), a = t * (BigInt(r) % e) % e, o = i.mulPointEscalar(i.Base8, t), s = i.mulPointEscalar(i.Base8, a);
		return {
			H0: [BigInt(i.F.toString(o[0])), BigInt(i.F.toString(o[1]))],
			H1: [BigInt(i.F.toString(s[0])), BigInt(i.F.toString(s[1]))]
		};
	});
	static getRandomizedStealthPair = p.attach((t, r) => {
		let i = n(), a = BigInt(r) % e, o = i.mulPointEscalar(i.Base8, t), s = i.mulPointEscalar(o, a);
		return {
			H0: [BigInt(i.F.toString(o[0])), BigInt(i.F.toString(o[1]))],
			H1: [BigInt(i.F.toString(s[0])), BigInt(i.F.toString(s[1]))]
		};
	});
	static getStealthAddressCompressedPoints = (e, t) => {
		let { H0: n, H1: r } = this.getRandomizedStealthPairOld(e, t), [i, o] = [n, r].map((e) => BigInt(e[1]) + 2n ** 255n * a(e[0]));
		return {
			h0: i,
			h1: o
		};
	};
	static checkSignature = (e, t, n, r) => {
		let { h0: i, h1: a } = this.getStealthAddressCompressedPoints(e, r);
		return t === i && n === a;
	};
	static getStealthAddress = h.attach((e, n) => {
		let { H0: r, H1: i } = this.getRandomizedStealthPairOld(e, n);
		return t(2n * a(r[0]) + a(i[0]), r[1], i[1]);
	});
	static getH1FromH0 = (t, r) => {
		let i = n(), a = BigInt(r) % e, o = [i.F.e(t[0]), i.F.e(t[1])], s = i.mulPointEscalar(o, a);
		return [BigInt(i.F.toString(s[0])), BigInt(i.F.toString(s[1]))];
	};
	static verifyStealthPair = (e, t, n, r = !0) => {
		let i = this.getH1FromH0(e, n);
		return r ? i[1] === t[1] : i === t;
	};
	static getStealthAddressNewStyle = (e, n, r) => {
		if (r?.length !== 2) throw Error("Spending public key must be an array of 2 elements");
		let i = this.getH1FromH0(e, n);
		return t(2n * a(e[0]) + a(i[0]), e[1], i[1], r[0], r[1], n);
	};
	static findCorrectRandomization(t, n) {
		if (!n) throw Error("No Private Shielded Key Provided");
		let r = BigInt(n) % e, i, a, o = 0n;
		do
			i = t * 10n ** o % e, a = i * r % e, o += 1n;
		while (a >= 2n ** 253n || i >= 2n ** 253n);
		return i;
	}
	static getH0FromRandomization = (e) => {
		let t = n(), r = t.mulPointEscalar(t.Base8, e);
		return [BigInt(t.F.toString(r[0])), BigInt(t.F.toString(r[1]))];
	};
	static findH0(e, t) {
		if (!t) return;
		let { H0: n } = this.getRandomizedStealthPair(e, t);
		return n;
	}
	static getEncryptionKeyPair = (e) => {
		let t = u.crypto_box_seed_keypair(o.getBytes(e));
		return {
			privateKey: o.hexlify(t.privateKey),
			publicKey: o.hexlify(t.publicKey)
		};
	};
	getAccessKey = () => (this.requireKeyMaterial(), t(this.getShieldedPrivateKey(), this.getShieldedPublicKey()));
	getBackendToken = () => (this.requireKeyMaterial(), t(this.getAccessKey(), this.getShieldedPublicKey()));
};
//#endregion
export { g as EncryptionKeyPairDefaultValue, _ as UserKeys, h as stealthAddressCacheDevice, p as stealthPairCacheDevice, m as stealthPairOldCacheDevice };
