agentUtils.ts 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import { tiers } from "../components/agent-tiers";
  2. import { ethers, formatUnits } from "ethers";
  3. import { UNIPAIR_ABI } from "@/utils/abi/uniswapPair";
  4. import { CONTRACT_ADDRESS } from "@/lib/provider";
  5. // Find the highest tier that the stakedAIUS qualifies for
  6. export type AgentTier = {
  7. name: "None" | "Newborn" | "Baby" | "Child" | "Teen" | "Adult";
  8. level: number;
  9. stakedAIUS: number;
  10. };
  11. // Calculates price based on tokenData and blockchain reserves
  12. export async function calculatePrice(
  13. contract: ethers.Contract,
  14. provider: ethers.Provider,
  15. pairContractCache: Map<string, ethers.Contract>,
  16. token0Cache: Map<string, string>,
  17. tokenData: any[],
  18. ): Promise<number[]> {
  19. if (tokenData.length <= 4) return [0, 0];
  20. const [erc20Token, , reserve0, reserve1, pairAddress] = tokenData;
  21. if (!erc20Token || !pairAddress) return [0, 0];
  22. if (!pairContractCache.has(pairAddress)) {
  23. pairContractCache.set(
  24. pairAddress,
  25. new ethers.Contract(pairAddress, UNIPAIR_ABI, provider),
  26. );
  27. }
  28. const pairContract = pairContractCache.get(pairAddress)!;
  29. if (!token0Cache.has(pairAddress)) {
  30. const token0 = await pairContract.token0();
  31. token0Cache.set(pairAddress, token0);
  32. }
  33. const token0 = token0Cache.get(pairAddress)!;
  34. const [aiusReserve, tokenReserve] =
  35. token0 === erc20Token ? [reserve1, reserve0] : [reserve0, reserve1];
  36. const aius = parseFloat(formatUnits(aiusReserve, 18));
  37. const tokens = parseFloat(formatUnits(tokenReserve, 18));
  38. if (tokens === 0) return [0, 0];
  39. return [aius, aius / tokens];
  40. }
  41. // Calculates tier based on AIUS staked amount or tokenId
  42. export async function calculateTier(
  43. contract: ethers.Contract,
  44. tokenId: number,
  45. price: number,
  46. stakedAius: number,
  47. tokenData: any[],
  48. ): Promise<AgentTier> {
  49. if (tokenData.length > 4) {
  50. const staked = stakedAius * 1; // price already calculated based on reserves
  51. const currentTierIndex = tiers
  52. .map((tier, index) => ({ ...tier, index }))
  53. .filter((tier) => staked >= tier.requiredAIUS)
  54. .sort((a, b) => b.requiredAIUS - a.requiredAIUS)[0];
  55. return {
  56. name: (currentTierIndex?.name as AgentTier["name"]) || "None",
  57. level: currentTierIndex?.index != null ? currentTierIndex.index : 0,
  58. stakedAIUS: staked,
  59. };
  60. } else {
  61. // fallback: get AIUS directly
  62. const [aius] = (await contract.getAiusAndOwed(
  63. tokenId,
  64. CONTRACT_ADDRESS,
  65. )) || [BigInt(0)];
  66. return {
  67. name: "None",
  68. level: 0,
  69. stakedAIUS: Number(formatUnits(aius, 18)),
  70. };
  71. }
  72. }