| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- import { supabase } from "@/utils/supabase";
- import { ethers } from "ethers";
- import { AgentTier, calculatePrice, calculateTier } from "@/utils/agentUtils";
- import type { Agent } from "@/types/agent";
- import {
- getEthcallProvider,
- getMainContract,
- getMainEthcallContract,
- getProvider,
- } from "@/lib/provider";
- import { decodeAgentId } from "@/utils/fileUtils";
- export async function getAgentsFromSupabase(agentId?: string | null) {
- const agentFields = [
- "id",
- "agentId",
- "name",
- "token",
- "description",
- "status",
- "avatar",
- "category",
- "tags",
- "vrmUrl",
- "bgUrl",
- "config",
- "integrations",
- "systemPrompt",
- "visionSystemPrompt",
- ].join(",");
- let query = supabase
- .from("agents")
- .select(agentFields)
- .neq("blackList", true);
- if (agentId) {
- query = query.eq("agentId", agentId);
- }
- const { data, error } = await query;
- if (error) throw error;
- return data;
- }
- // Fetch and enrich agents with price and tier info
- export async function fetchAgentStats(
- agents: Agent | Agent[],
- ): Promise<Agent | Agent[]> {
- const agentArray = Array.isArray(agents) ? agents : [agents];
- const provider = getProvider();
- const contract = getMainContract();
- const pairContractCache = new Map<string, ethers.Contract>();
- const token0Cache = new Map<string, string>();
- const updatedAgents: Agent[] = [];
- for (const agent of agentArray) {
- const tokenId = Number(agent.id);
- let price = 0;
- let stakedAius = 0;
- let erc20: `0x${string}` = '0x';
- let tier: AgentTier = { name: "None", level: 0, stakedAIUS: 0 };
- try {
- // Get erc20 ca
- const tokenURI = await contract.tokenURI(tokenId);
- const base64 = tokenURI.replace(/^data:application\/json;base64,/, "");
- const jsonStr = Buffer.from(base64, "base64").toString("utf-8");
- const metadata = JSON.parse(jsonStr);
- const erc20Attr = metadata.attributes?.find(
- (attr: any) => attr.trait_type === "ERC20 Address"
- );
- erc20 = erc20Attr.value;
- const tokenData = await contract.getTokenData(tokenId);
- [stakedAius, price] = await calculatePrice(
- contract,
- provider,
- pairContractCache,
- token0Cache,
- tokenData,
- );
- tier = await calculateTier(
- contract,
- tokenId,
- price,
- stakedAius,
- tokenData,
- );
- } catch (err) {
- const reason = (err as any)?.revert?.args?.[0] ?? (err as any)?.reason;
- if (reason === "Pair not created") {
- console.warn(`Token ${tokenId}: Pair not created`);
- } else {
- console.warn(
- `Failed to calculate price/tier for token ${tokenId}`,
- err,
- );
- }
- }
- updatedAgents.push({ ...agent, price, tier, erc20 });
- }
- // Return a single Agent if the input was a single Agent
- return Array.isArray(agents) ? updatedAgents : updatedAgents[0];
- }
- export const METADATA_KEYS = [
- "agent_id",
- "name",
- "description",
- "image",
- "vrm_url",
- "bg_url",
- "tags",
- "agent_category",
- "chatbot_backend",
- "tts_backend",
- "stt_backend",
- "vision_backend",
- "brain",
- "virtuals",
- "eacc",
- "uos",
- "system_prompt",
- "vision_system_prompt",
- ];
- export async function getAgentFromContract(
- agentId: string,
- ): Promise<Agent | null> {
- const ethcallContract = getMainEthcallContract();
- const ethcallProvider = await getEthcallProvider();
- const tokenId = decodeAgentId(agentId);
- const [metadata] = await ethcallProvider.all([
- ethcallContract.getMetadata(tokenId, METADATA_KEYS),
- ]);
- if (
- !Array.isArray(metadata) ||
- metadata.length === 0 ||
- metadata[0] === "0x"
- ) {
- console.warn(`No metadata found for tokenId: ${tokenId}`);
- return null;
- }
- const [
- agentid,
- name,
- description,
- image,
- vrmUrl,
- bgUrl,
- tags,
- agentCategory,
- chatbot,
- tts,
- stt,
- vision,
- brain,
- virtuals,
- eacc,
- uos,
- systemPrompt,
- visionSystemPrompt,
- ] = metadata;
- const integrations: Record<string, string> = {};
- if (brain) integrations.brain = brain;
- if (virtuals) integrations.virtuals = virtuals;
- if (eacc) integrations.eacc = eacc;
- if (uos) integrations.uos = uos;
- const agent: Agent = {
- id: `${tokenId}`,
- agentId: agentid,
- name: name || "Unknown",
- token: "AINFT",
- description: description || "No description available",
- price: 0,
- status: "status",
- avatar: image,
- category: agentCategory || "All Agents",
- tags: tags?.split(",") || [],
- tier: { name: "None", level: 0, stakedAIUS: 0 },
- vrmUrl,
- bgUrl,
- config: {
- chatbot,
- tts,
- stt,
- vision,
- amicaLife: "amicaLife",
- rvc: "rvc",
- },
- integrations,
- systemPrompt,
- visionSystemPrompt,
- };
- return agent;
- }
- type SupportedNetworks =
- | "mainnet"
- | "sepolia"
- | "arbitrum"
- | "arbitrumSepolia";
- export function getExplorerUrl(address: `0x${string}`, network: SupportedNetworks = "sepolia"): string {
- const explorerBaseMap: Record<SupportedNetworks, string> = {
- mainnet: "https://etherscan.io",
- sepolia: "https://sepolia.etherscan.io",
- arbitrum: "https://arbiscan.io",
- arbitrumSepolia: "https://sepolia.arbiscan.io",
- };
- const base = explorerBaseMap[network];
- return `${base}/address/${address}`;
- }
|