import { ContractType as e } from "../../types/ethereum-network.types.mjs";
import { chainIds as t } from "../../constants/chains.constants.mjs";
import { TokenType as n } from "../../constants/protocol.constants.mjs";
import { StorageKeys as r } from "../../types/cache.types.mjs";
import { caseInsensitiveEqual as i, lowerCaseIncludes as a } from "../../functions/utils/caseInsensitive.utils.mjs";
import { API as o } from "../../API/API.mjs";
import { Logger as s } from "../../error-handling/logger.mjs";
import { getStateKey as c } from "../../functions/utils/string.utils.mjs";
import { tokenVisibilityStorage as l } from "./token-visibility-db.mjs";
import { getContractWithFetcherByChainId as u } from "../../functions/web3/getContractMetadata.mjs";
import d from "axios";
import { get as f, update as p } from "idb-keyval";
//#region libs/shared/common/src/data-structures/TokenDBs/ArcPublicTokensDB.ts
var m = class {
	API_BASE = "https://testnet.arcscan.app/api";
	fetchedTokens = {};
	async getPublicTokens(e) {
		let n = c(e, t.arcTestnet);
		return (await f(r.ARC_PUBLIC_TOKENS))?.[n] || [];
	}
	getFetchedTokens(e) {
		let n = c(e, t.arcTestnet);
		return this.fetchedTokens[n] || [];
	}
	async fetchAndUpdatePublicTokens(e) {
		let s = c(e, t.arcTestnet), u = await this.getERC20TokenAddresses(e), d = await this.getNFTTokens(e), f = d.map((e) => e.contractAddress), m = [...u, ...f];
		if (!m.length) return;
		let h = (await o.tokensInfoCall(t.arcTestnet, m)).map((e, r) => {
			if (e) return e;
			let a = m[r], o = d.find((e) => i(e.contractAddress, a));
			return o && o.tokenIds && o.tokenIds.length > 0 ? {
				chainId: t.arcTestnet,
				name: "Unknown NFT",
				symbol: "NFT",
				erc20TokenAddress: a,
				decimals: 0,
				nftTokenType: n.ERC721,
				tokenIds: o.tokenIds
			} : null;
		}).filter((e) => !!e), g = await l.hideSpamsAndFetchHiddenTokensAddresses(t.arcTestnet, h), _ = h.filter((e) => !a(g, e.erc20TokenAddress)).map((e) => ({
			...e,
			tokenIds: d.find((t) => i(t.contractAddress, e.erc20TokenAddress))?.tokenIds
		}));
		await p(r.ARC_PUBLIC_TOKENS, (e = {}) => {
			let t = {
				...e,
				[s]: _
			};
			return this.fetchedTokens = t, t;
		});
	}
	async getERC20TokenAddresses(n) {
		let r = [];
		try {
			let i = (await d.post(`${this.API_BASE}?module=account&action=tokentx&address=${n}`)).data;
			if (i.status === "1" && i.result) {
				let a = [...new Set(i.result.map(({ contractAddress: e }) => e))];
				for (let i of a) try {
					let a = u(t.arcTestnet, e.ERC20Contract, i), o = BigInt(await a.balanceOf(n));
					o > 0n && r.push({
						contractAddress: i,
						tokenBalance: o.toString()
					});
				} catch (e) {
					s.error("Error fetching ARC testnet token balance:", e);
				}
			}
		} catch (e) {
			s.error("Error fetching ARC testnet token transactions:", e);
		}
		return r.filter(({ tokenBalance: e }) => Number(e) !== 0).map(({ contractAddress: e }) => e);
	}
	async getNFTTokens(e) {
		let t = `${this.API_BASE}/v2/addresses/${e}/nft?type=ERC-721,ERC-1155`, n = [], r;
		do {
			let e = r ? `&${new URLSearchParams(r)}` : "", { data: i } = await d.get(`${t}${e}`), { items: a = [], next_page_params: o } = i;
			n.push(...a), r = o ? {
				token_contract_address_hash: o.token_contract_address_hash,
				token_id: o.token_id,
				token_type: o.token_type
			} : void 0;
		} while (r);
		let i = n.reduce((e, t) => {
			let n = t.token.address_hash.toLowerCase(), r = t.id;
			return e.has(n) || e.set(n, []), e.get(n)?.push(r), e;
		}, /* @__PURE__ */ new Map());
		return Array.from(i.entries()).map(([e, t]) => ({
			contractAddress: e,
			tokenIds: t
		}));
	}
}, h = new m();
//#endregion
export { m as ArcPublicTokensDB, h as arcPublicTokensDB };
