import { HINKAL_SUPPORTED_CHAINS as e, isSolanaLike as t, networkRegistry as n } from "../constants/chains.constants.mjs";
import { CallsStatus as r } from "../types/eip5792.types.mjs";
import { UserFriendlyErrorCodes as i, transactionErrorCodes as a } from "../error-handling/error-codes.constants.mjs";
import { Logger as o } from "../error-handling/logger.mjs";
import { createJsonRpcProvider as s } from "../functions/utils/create-provider.mjs";
import { getContract as c } from "../functions/web3/getContractMetadata.mjs";
import { ethers as l } from "ethers";
import { ConnectorAlreadyConnectedError as u } from "wagmi";
import { connect as d, disconnect as f, getAccount as p, reconnect as m, signMessage as h, switchChain as g, watchAccount as _, watchChainId as v } from "wagmi/actions";
//#region libs/shared/common/src/providers/WagmiProviderAdapter.ts
var y = class {
	connector;
	chainId;
	originalProvider;
	fetchProviders = {};
	signer;
	chainEventListener;
	config;
	unsubscribeFns = [];
	constructor() {
		e.forEach((e) => {
			if (t(e)) return;
			let { fetchRpcUrl: r } = n[e];
			if (!r) throw Error("No Fetch RPC URL In Provider Adapter");
			this.fetchProviders[e] = r.includes("wss") ? new l.WebSocketProvider(r) : s(e);
		});
	}
	initConnector(e) {
		this.connector = e;
	}
	initConfig(e) {
		this.config = e;
	}
	async init(e) {
		if (!this.connector) throw Error("No Connector In Provider Adapter");
		if (e && (this.chainId = e), !this.chainId) throw Error("No Chain Id In Provider Adapter");
		let t = await this.connector.getProvider();
		this.originalProvider = new l.BrowserProvider(t);
		let n = (await this.connector.getAccounts())?.[0];
		if (!n) {
			this.chainEventListener && this.chainEventListener.onChainChanged();
			return;
		}
		this.signer = await this.walletClientToSigner({
			transport: t,
			account: n
		}, this.chainId);
	}
	async disconnectFromConnector() {
		if (!this.config) throw Error("No Config In Provider Adapter");
		this.release(), await f(this.config);
	}
	async connectToConnector(e) {
		if (!this.config) throw Error("No Config In Provider Adapter");
		if (e.id === "walletConnect") try {
			await m(this.config, { connectors: [e] }), await f(this.config);
		} catch {}
		try {
			return (await d(this.config, { connector: e })).chainId;
		} catch (t) {
			if (t instanceof u) return e.getChainId();
			let n = a.CONNECTION_FAILED;
			throw t?.code === 4001 && (n = i.YOU_CANCELED_REQUEST), Error(n);
		}
	}
	getChainId() {
		return this.chainId;
	}
	async waitForTransaction(e, t, n) {
		if ((await this.fetchProviders[e]?.waitForTransaction(t, n))?.status) return !0;
		throw Error(a.TRANSACTION_NOT_CONFIRMED);
	}
	async signMessage(e) {
		if (!this.config) throw Error("No Config In Provider Adapter");
		let t = await h(this.config, { message: e });
		if (!t) throw Error(a.SIGNING_FAILED);
		if (t.includes("error")) throw Error(a.SIGNATURE_UNSUPPORTED_PERSONAL_SIGN);
		return t;
	}
	async signTypedData(e, t, n) {
		return this.signer.signTypedData(e, t, n);
	}
	async switchNetwork(e) {
		if (!this.config) throw Error("No Config In Provider Adapter");
		return g(this.config, { chainId: e.chainId });
	}
	async getAddress() {
		if (!this.config) throw Error("No Config In Provider Adapter");
		let { address: e } = p(this.config);
		if (!e) throw Error("IllegalState");
		return l.getAddress(e);
	}
	setChainEventListener(e) {
		if (!this.config) throw Error("No Config In Provider Adapter");
		this.chainEventListener = e, this.chainEventListener && (this.unsubscribeFns.push(_(this.config, { onChange: ({ address: e }, { address: t }) => {
			this.chainEventListener && e !== t && this.chainEventListener.onAccountChanged();
		} })), this.unsubscribeFns.push(v(this.config, { onChange: (e) => {
			this.chainEventListener && this.chainEventListener.onChainChanged(e);
		} })));
	}
	onAccountChanged() {
		return this.init();
	}
	onChainChanged(e) {
		return this.init(e);
	}
	release() {
		this.removeListeners();
	}
	removeListeners() {
		this.unsubscribeFns.forEach((e) => e()), this.unsubscribeFns = [];
	}
	getContract(e, t, n = void 0, r) {
		return c(t, e, n, r);
	}
	getContractWithSigner(e, t, n = void 0) {
		if (!this.signer) throw Error("IllegalState: no signer");
		return this.getContract(e, t, n, this.signer);
	}
	getContractWithFetcher(e, t, n = void 0) {
		let r = this.fetchProviders[e];
		if (!r) throw Error("fetchProvider not initialized");
		return this.getContract(e, t, n, r);
	}
	async sendTransaction(e) {
		if (!this.signer) throw Error("IllegalState: no signer");
		return await this.signer.sendTransaction(e);
	}
	async connectAndPatchProvider(e) {
		return await this.connectToConnector(e);
	}
	isPermitterAvailable() {
		if (!this.chainId) throw Error("Illegal state: no chainId");
		return !!n[this.chainId]?.contractData?.permitterAddress;
	}
	async getGasPrice(e) {
		let t = (await this.fetchProviders[e]?.getFeeData())?.gasPrice;
		if (!t) throw Error("Could not fetch gas price in getGasPrice");
		return t;
	}
	async walletClientToSigner(e, t) {
		let { account: n, transport: r } = e;
		return new l.BrowserProvider(r).getSigner(n);
	}
	async supportsBatchCall(e) {
		if (!this.originalProvider) return !1;
		try {
			let t = await this.getAddress(), n = `0x${e.toString(16)}`, r = await this.originalProvider.send("wallet_getCapabilities", [t, [n]]), i = r?.[n] || r?.["0x0"];
			if (!i?.atomic) return !1;
			let a = typeof i.atomic == "string" ? i.atomic : i.atomic?.status;
			return a === "supported" || a === "ready";
		} catch {
			return !1;
		}
	}
	async waitForBatchTransactionStatus(e) {
		if (!this.originalProvider) throw Error("WagmiProviderAdapter: Provider not initialized");
		for (let t = 0; t < 60; t += 1) {
			await new Promise((e) => {
				setTimeout(() => e(), 1e3);
			});
			try {
				let t = await this.originalProvider.send("wallet_getCallsStatus", [e]);
				if (t.status === r.Confirmed && t.receipts?.[0]?.transactionHash) return t.receipts[0].transactionHash;
				if (t.status === r.OffchainFailure || t.status === r.ChainFailure || t.status === r.PartialFailure) break;
			} catch (e) {
				o.log("waitForBatchTransactionStatus:", e);
			}
		}
		throw Error("Batch transaction timed out or failed");
	}
	async sendBatchCallsTransaction(e, t) {
		if (!this.fetchProviders[e]) throw Error("WagmiProviderAdapter: fetchProvider not initialized");
		if (!this.originalProvider) throw Error("WagmiProviderAdapter: Provider not initialized");
		let n = await this.getAddress(), r = {
			version: "2.0.0",
			chainId: `0x${e.toString(16)}`,
			from: n,
			atomicRequired: !0,
			calls: t
		}, i = await this.originalProvider.send("wallet_sendCalls", [r]), a = i?.id || i;
		if (!a || typeof a != "string") throw Error("Invalid batch ID received from wallet_sendCalls");
		let o = await this.waitForBatchTransactionStatus(a), s = await this.fetchProviders[e].getTransaction(o);
		if (!s) throw Error("Transaction not found");
		return s;
	}
}, b = new y(), x = () => new y();
//#endregion
export { x as default, b as wagmiProviderAdapter };
