import { isSolanaLike as e, isTronLike as t, networkRegistry as n } from "../../constants/chains.constants.mjs";
import "../../constants/protocol.constants.mjs";
import { ContractType as r } from "../../types/ethereum-network.types.mjs";
import { countTotalAmountInUtxos as i } from "../../functions/utils/amounts.utils.mjs";
import { ExternalActionId as a } from "../../types/external-action.types.mjs";
import { AdminTransactionType as o } from "../../types/admin.types.mjs";
import "../../types/index.mjs";
import { transactionErrorCodes as s } from "../../error-handling/error-codes.constants.mjs";
import { randomBigInt as c } from "../../functions/web3/etherFunctions.mjs";
import { getCurrentTimeInSeconds as l } from "../../functions/utils/time.utils.mjs";
import { Utxo as u } from "../utxo/Utxo.mjs";
import { encodeTokenWithId as d } from "../../functions/utils/encodeTokenWithId.mjs";
import { addressToHexFormat as f, reorderZkCallData as p } from "../../functions/utils/tron.utils.mjs";
import { getInputUtxoAndBalancePerToken as m } from "../../functions/web3/events/getInputUtxoAndBalance.mjs";
import { validateAndGetChainId as h } from "../../functions/utils/token-check.utils.mjs";
import { addPaddingToUtxos as g } from "../../functions/web3/events/getShieldedBalance.mjs";
import { outputUtxoProcessing as _ } from "../../functions/pre-transaction/outputUtxoProcessing.mjs";
import { calcEncryptedOutputs as v } from "../../functions/snarkjs/common.snarkjs.mjs";
import { constructAdminData as y } from "../../functions/pre-transaction/constructAdminData.mjs";
import { getFeeStructure as b } from "../../functions/pre-transaction/getFeeStructure.mjs";
import { shouldPatchAccessTokenMerkleTree as x } from "../../functions/pre-transaction/shouldPatchAccessTokenMerkleTree.mjs";
import { getKycAndSignatureData as S } from "../../functions/pre-transaction/getKycAndSignatureData.mjs";
import { buildCommitmentValidationData as C } from "../../functions/pre-transaction/buildCommitmentValidationData.mjs";
import "../../functions/pre-transaction/index.mjs";
import { RELAYER_TX_CONFIRMATION_TIMEOUT as w } from "../../constants/tx-confirmation.constants.mjs";
import { waitForTransactionConfirmation as T } from "../../functions/utils/tx-confirmation.utils.mjs";
import { constructZkProof as E } from "../../functions/snarkjs/constructGeneralZkProof.mjs";
import { constructSolanaZkProof as D } from "../../functions/snarkjs/constructSolanaZkProof.mjs";
import { solanaTransactCallRelayer as O, transactCallRelayer as k } from "../../functions/web3/functionCalls/transactCallRelayer.mjs";
import { mergeWithFeeStructure as A } from "../../functions/pre-transaction/merge-with-fee-structure.mjs";
import { ethers as j } from "ethers";
//#region libs/shared/common/src/data-structures/Hinkal/hinkalWithdrawStuckUtxos.ts
var M = async (e, t, n, r) => {
	let i = [...await g(e, t, n, r, void 0, void 0, !1, !0)], a = [], o = l().toString();
	for (let t = 0; t < n.length; t += 1) {
		let { outputUtxos: n } = _(e.userKeys, i[t], r[t], o);
		a.push(n);
	}
	return {
		inputUtxosArray: i,
		outputUtxosArray: a
	};
}, N = async (e, t, n, r) => {
	let i = [...await g(e, t, n, r, 6, void 0, !1, !0)][0], a = l().toString(), { outputUtxos: o } = _(e.userKeys, i, r[0], a, void 0, !1);
	return {
		inputUtxos: i,
		outputUtxos: o
	};
}, P = async (e, n, i, c, l) => {
	let u = t(n), d = [i.erc20TokenAddress], m = i.erc20TokenAddress, [h, g, _] = await Promise.all([
		b(n, m, d, a.Transact),
		e.getRandomRelay(n, !0),
		e.getEthereumAddressByChain(n)
	]), v = f(_);
	if (!g) throw Error(s.RELAYER_NOT_AVAILABLE);
	let x = f(l), w = c - h.flatFee;
	if (w <= 0n) throw Error(`Insufficient balance to cover fee. Balance: ${c}, Fee: ${h.flatFee}`);
	let T = [-w];
	A(n, d, T, h);
	let D = {
		externalActionId: 0n,
		externalAddress: x,
		externalActionMetadata: "0x00"
	}, [{ patchAccessTokenMerkleTree: O, signatureData: j }, { inputUtxosArray: N, outputUtxosArray: P }] = await Promise.all([S(e, n, d, T, v), M(e, n, d, T)]), F = `swapperM${T.length.toString()}x${N[0].length}x1`, [{ zkCallData: I, circomData: L, dimData: R }, z] = await Promise.all([E(e.merkleTreeHinkalByChain[n], e.merkleTreeAccessTokenByChain[n], N, P, e.userKeys, F, D.externalActionId, D.externalAddress, D.externalActionMetadata, e.generateProofRemotely, g, n, void 0, void 0, void 0, O, void 0, h, e.getContractWithFetcher(n, r.HinkalHelperContract), j), C(n, e.userKeys, d, N)]), B = await p(u, I, R, L);
	return {
		tx: await k(n, I, R, L, z, void 0, void 0, y(o.WithdrawOnChainUtxos, n, d, T, v), B),
		amountToRecipient: w
	};
}, F = async (e, t, r, i, o, l) => {
	let d = [r.erc20TokenAddress], { originalDeployer: f, hinkalIdl: p } = n[t].contractData;
	if (!f || !p) throw Error("missing data");
	let { userKeys: m, merkleTreeAccessTokenByChain: h, merkleTreeHinkalByChain: g } = e, _ = r.erc20TokenAddress, [y, S, w] = await Promise.all([
		b(t, _, d, a.Transact, void 0, void 0, {
			mintTo: d[0],
			recipient: o,
			nullifierCount: l
		}),
		e.getRandomRelay(t, !0),
		e.getEthereumAddressByChain(t)
	]);
	if (!S) throw Error(s.RELAYER_NOT_AVAILABLE);
	let T = i - y.flatFee;
	if (T <= 0n) throw Error(`Insufficient balance to cover fee. Balance: ${i}, Fee: ${y.flatFee}`);
	let E = [-T];
	E[0] -= y.flatFee;
	let [{ patchAccessTokenMerkleTree: k, kycRequired: A, hasAccessToken: M }, { inputUtxos: P, outputUtxos: F }] = await Promise.all([x(e, t, d, E), N(e, t, d, E)]), I = u.findCorrectRandomization(c(31), e.userKeys.getShieldedPrivateKey()), L = {
		tokenNumber: d.length,
		nullifierAmount: P.length,
		outputAmount: F.length
	}, R = e.getSolanaProgram(p), z = v([F])[0][0], B = Array.from(j.getBytes(z)), [{ proofAArr: V, proofBArr: H, proofCArr: U, publicInputsArr: W }, G] = await Promise.all([D(e.generateProofRemotely, f, g[t], h[t], m, R, [d[0]], [P], [F], I, y.flatFee, y.variableRate, o, S, L, [B], t, k), C(t, m, d, [P])]), K = {
		recipient: o,
		mint: d[0] === "11111111111111111111111111111111" ? void 0 : d[0]
	};
	return {
		tx: await O({
			chainId: t,
			relayAddress: S,
			functionName: "transact",
			args: {
				proofAArr: V,
				proofBArr: H,
				proofCArr: U,
				publicInputsArr: W,
				encryptedOutputs: [B],
				relayerFee: y.flatFee.toString(),
				dimensions: L
			},
			accounts: K,
			commitmentValidationData: G,
			solanaAccessTokenData: !M && A ? {
				ethereumAddress: w,
				accessKey: m.getAccessKey()
			} : void 0
		}),
		amountToRecipient: T
	};
}, I = async (t, n, r, i, a, o) => e(n) ? F(t, n, r, i, a, o) : P(t, n, r, i, a), L = async (e, t, n) => {
	let r = [], a = h([t]), o = d(a, {
		erc20TokenAddress: t.erc20TokenAddress,
		tokenId: 0
	});
	for (;;) {
		await e.resetMerkleTreesIfNecessary([a]);
		let s = ((await m({
			hinkal: e,
			sliceIfMore6: !1,
			useBlockedUtxos: !0,
			chainId: a,
			allowRemoteDecryption: e.generateProofRemotely
		}))?.get(o) ?? []).filter((e) => e.amount > 0n).sort((e, t) => Number(t.amount - e.amount)).slice(0, 6), c = i(s);
		if (!c) break;
		let { tx: l } = await I(e, a, t, c, n, s.length);
		await T(a, l, {
			solanaCommitment: "finalized",
			evmTimeoutMs: w
		}), r.push(l);
	}
	return r;
};
//#endregion
export { L as hinkalWithdrawStuckUtxos };
