import { HINKAL_SUPPORTED_CHAINS as e, getOnchainChainId as t, isSolanaLike as n, networkRegistry as r } from "../constants/chains.constants.mjs";
import { CallsStatus as i } from "../types/eip5792.types.mjs";
import { UserFriendlyErrorCodes as a, transactionErrorCodes as o } from "../error-handling/error-codes.constants.mjs";
import { Logger as s } from "../error-handling/logger.mjs";
import { createJsonRpcProvider as c } from "../functions/utils/create-provider.mjs";
import { getContract as l } from "../functions/web3/getContractMetadata.mjs";
import { ethers as u } from "ethers";
import { ConnectorAlreadyConnectedError as d } from "wagmi";
import { connect as f, disconnect as p, getAccount as m, reconnect as h, signMessage as g, switchChain as _, watchAccount as v, watchChainId as y } from "wagmi/actions";
//#region libs/shared/common/src/providers/WagmiProviderAdapter.ts
var b = class b {
	connector;
	chainId;
	originalProvider;
	fetchProviders = {};
	signer;
	chainEventListener;
	config;
	unsubscribeFns = [];
	constructor() {
		e.forEach((e) => {
			if (n(e)) return;
			let { fetchRpcUrl: t } = r[e];
			if (!t) throw Error("No Fetch RPC URL In Provider Adapter");
			this.fetchProviders[e] = t.includes("wss") ? new u.WebSocketProvider(t) : c(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 u.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 p(this.config);
	}
	async connectToConnector(e) {
		if (!this.config) throw Error("No Config In Provider Adapter");
		if (e.id === "walletConnect") try {
			await h(this.config, { connectors: [e] }), await p(this.config);
		} catch {}
		try {
			return (await f(this.config, { connector: e })).chainId;
		} catch (t) {
			if (t instanceof d) return e.getChainId();
			let n = o.CONNECTION_FAILED;
			throw t?.code === 4001 && (n = a.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(o.TRANSACTION_NOT_CONFIRMED);
	}
	async signMessage(e) {
		if (!this.config) throw Error("No Config In Provider Adapter");
		let t = await g(this.config, { message: e });
		if (!t) throw Error(o.SIGNING_FAILED);
		if (t.includes("error")) throw Error(o.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");
		let n = t(e.chainId);
		return _(this.config, { chainId: n });
	}
	async getAddress() {
		if (!this.config) throw Error("No Config In Provider Adapter");
		let { address: e } = m(this.config);
		if (!e) throw Error("IllegalState");
		return u.getAddress(e);
	}
	setChainEventListener(e) {
		if (!this.config) throw Error("No Config In Provider Adapter");
		this.chainEventListener = e, this.chainEventListener && (this.unsubscribeFns.push(v(this.config, { onChange: ({ address: e }, { address: t }) => {
			this.chainEventListener && e !== t && this.chainEventListener.onAccountChanged();
		} })), this.unsubscribeFns.push(y(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 l(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 !!r[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;
	}
	static FALLBACK_METHODS = new Set(["eth_blockNumber", "eth_call"]);
	wrapTransportWithRpcFallback(e, t) {
		let n = this.fetchProviders[t];
		return n ? { request: async (t) => {
			let r = await e.request(t);
			return r == null && b.FALLBACK_METHODS.has(t.method) ? n.send(t.method, Array.isArray(t.params) ? t.params : []) : r;
		} } : e;
	}
	async walletClientToSigner(e, t) {
		let { account: n, transport: r } = e;
		return new u.BrowserProvider(this.wrapTransportWithRpcFallback(r, t)).getSigner(n);
	}
	async supportsBatchCall(e) {
		if (!this.originalProvider) return !1;
		try {
			let n = await this.getAddress(), r = `0x${t(e).toString(16)}`, i = await this.originalProvider.send("wallet_getCapabilities", [n, [r]]), a = i?.[r] || i?.["0x0"];
			if (!a?.atomic) return !1;
			let o = typeof a.atomic == "string" ? a.atomic : a.atomic?.status;
			return o === "supported" || o === "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 === i.Confirmed && t.receipts?.[0]?.transactionHash) return t.receipts[0].transactionHash;
				if (t.status === i.OffchainFailure || t.status === i.ChainFailure || t.status === i.PartialFailure) break;
			} catch (e) {
				s.log("waitForBatchTransactionStatus:", e);
			}
		}
		throw Error("Batch transaction timed out or failed");
	}
	async sendBatchCallsTransaction(e, n) {
		if (!this.fetchProviders[e]) throw Error("WagmiProviderAdapter: fetchProvider not initialized");
		if (!this.originalProvider) throw Error("WagmiProviderAdapter: Provider not initialized");
		let r = await this.getAddress(), i = {
			version: "2.0.0",
			chainId: `0x${t(e).toString(16)}`,
			from: r,
			atomicRequired: !0,
			calls: n
		}, a = await this.originalProvider.send("wallet_sendCalls", [i]), o = a?.id || a;
		if (!o || typeof o != "string") throw Error("Invalid batch ID received from wallet_sendCalls");
		let s = await this.waitForBatchTransactionStatus(o), c = await this.fetchProviders[e].getTransaction(s);
		if (!c) throw Error("Transaction not found");
		return c;
	}
}, x = new b(), S = () => new b();
//#endregion
export { b as WagmiProviderAdapter, S as default, x as wagmiProviderAdapter };
