diff --git a/.env.example b/.env.example index d2d1d9b..b0b7f82 100644 --- a/.env.example +++ b/.env.example @@ -1,6 +1,7 @@ -VITE_DLP_ADDRESS = -VITE_STAKING_ADDRESS = -VITE_TOKEN_ADDRESS = -VITE_RPC_URL = -VITE_TEE_POOL_ADDRESS = -VITE_DF_BASE_URL = \ No newline at end of file +VITE_DLP_ADDRESS= +VITE_STAKING_ADDRESS= +VITE_TOKEN_ADDRESS= +VITE_RPC_URL= +VITE_TEE_POOL_ADDRESS= +VITE_DF_BASE_URL= +VITE_INDEXER_BASE_URL= \ No newline at end of file diff --git a/src/api/createAiTokenGatingConfig.ts b/src/api/createAiTokenGatingConfig.ts new file mode 100644 index 0000000..d6adec6 --- /dev/null +++ b/src/api/createAiTokenGatingConfig.ts @@ -0,0 +1,24 @@ +import { httpAiAgent, type ApiResponse } from "../lib/http/http"; + +export interface IAiTokenGatingResponse { + id: string; + createdAt: string; + updatedAt: string; + stakeThreshold: number; + balanceThreshold: number; +} + +export interface ICreateTokenGatingConfigParams { + stakeThreshold: number; + balanceThreshold: number; +} + +export async function createAiTokenGatingConfig(params: ICreateTokenGatingConfigParams) { + try { + const response: ApiResponse = await httpAiAgent.post(`/token-gating-configs`, params); + + return response.data; + } catch (error) { + throw error; + } +} diff --git a/src/api/fetchAITokenGating.ts b/src/api/fetchAITokenGating.ts new file mode 100644 index 0000000..f289896 --- /dev/null +++ b/src/api/fetchAITokenGating.ts @@ -0,0 +1,18 @@ +import { httpAiAgent, type ApiResponse } from "../lib/http/http"; + +export interface IAiTokenGatingResponse { + id: string; + createdAt: string; + updatedAt: string; + stakeThreshold: string; + balanceThreshold: string; +} +export async function fetchAiTokenGating() { + try { + const response: ApiResponse = await httpAiAgent.get(`/token-gating-configs/latest`); + + return response.data; + } catch (error) { + throw error; + } +} diff --git a/src/api/fetchAvgChatsPerContributor.ts b/src/api/fetchAvgChatsPerContributor.ts index d4b23f4..63153ed 100644 --- a/src/api/fetchAvgChatsPerContributor.ts +++ b/src/api/fetchAvgChatsPerContributor.ts @@ -5,7 +5,7 @@ import { http, type ApiResponse } from "$lib/http/http"; export async function fetchAvgChatsPerContributor() { try { - const response: ApiResponse = await http.get(`/api/stats/average-chats-per-contributor`); + const response: ApiResponse = await http.get(`/stats/average-chats-per-contributor`); return response; } catch (error) { diff --git a/src/api/fetchChatInfo.ts b/src/api/fetchChatInfo.ts deleted file mode 100644 index 012a405..0000000 --- a/src/api/fetchChatInfo.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { http, type ApiResponse } from "../lib/http/http"; - -interface IResponse { - totalAccounts: number; - totalSubmissions: number; - totalChats: number; -} - -export async function fetchChatInfo() { - try { - const response: ApiResponse = await http.get("/api/submissions/submission-data"); - - return response; - } catch (error) { - throw error; - } -} \ No newline at end of file diff --git a/src/api/fetchChatStats.ts b/src/api/fetchChatStats.ts index 191a3fa..40cc6fb 100644 --- a/src/api/fetchChatStats.ts +++ b/src/api/fetchChatStats.ts @@ -18,7 +18,7 @@ export async function fetchChatStats(params: IChatStatsParams) { const queryString = generateQuery({ startDate, endDate }); try { - const response: ApiResponse = await http.get(`/api/stats/chats-stats${queryString}`); + const response: ApiResponse = await http.get(`/stats/chats-stats${queryString}`); return response.data; } catch (error) { diff --git a/src/api/fetchDailyUniqueContributors.ts b/src/api/fetchDailyUniqueContributors.ts index 6e0ce25..affc236 100644 --- a/src/api/fetchDailyUniqueContributors.ts +++ b/src/api/fetchDailyUniqueContributors.ts @@ -18,7 +18,7 @@ export async function fetchDailyUniqueContributors(params: IDailyUniqueContribut const query = generateQuery({ startDate, endDate }); try { - const response: ApiResponse = await http.get(`/api/stats/daily-unique-contributors${query}`); + const response: ApiResponse = await http.get(`/stats/daily-unique-contributors${query}`); return response; } catch (error) { diff --git a/src/api/fetchNetTokenFlow.ts b/src/api/fetchNetTokenFlow.ts new file mode 100644 index 0000000..83f65df --- /dev/null +++ b/src/api/fetchNetTokenFlow.ts @@ -0,0 +1,28 @@ +import { generateQuery } from "$lib/utils"; +import { httpIndexRequest, type ApiResponse } from "../lib/http/http"; + +export interface INetTokenFlowResponse { + totalStakeAmount: string + totalUnstakeAmount: string + netFlow: string + dailyNetFlow: string + weeklyNetFlow: string +} + +interface INetTokenFlowParams { + startDate: string + endDate: string +} + +export async function fetchNetTokenFlow(params: INetTokenFlowParams) { + const { startDate, endDate } = params; + const query = generateQuery({ startDate, endDate }); + + try { + const response: ApiResponse = await httpIndexRequest.get(`/staking-events/token-flow-info${query}`); + + return response.data; + } catch (error) { + throw error; + } +} \ No newline at end of file diff --git a/src/api/fetchNewChatsPerDay.ts b/src/api/fetchNewChatsPerDay.ts index 2544bf2..5bb880d 100644 --- a/src/api/fetchNewChatsPerDay.ts +++ b/src/api/fetchNewChatsPerDay.ts @@ -18,7 +18,7 @@ export async function fetchNewChatsPerDay(params: INewChatsPerDayParams) { const query = generateQuery({ startDate, endDate }); try { - const response: ApiResponse = await http.get(`/api/stats/new-chats-per-day${query}`); + const response: ApiResponse = await http.get(`/stats/new-chats-per-day${query}`); return response; } catch (error) { diff --git a/src/api/fetchRefreshedChatsCount.ts b/src/api/fetchRefreshedChatsCount.ts index 044df53..6911b8c 100644 --- a/src/api/fetchRefreshedChatsCount.ts +++ b/src/api/fetchRefreshedChatsCount.ts @@ -13,7 +13,7 @@ export async function fetchRefreshedChatsCount(params: IRefreshedChatsCountParam const query = generateQuery({ startDate, endDate }); try { - const response: ApiResponse = await http.get(`/api/stats/refreshed-chats-count${query}`); + const response: ApiResponse = await http.get(`/stats/refreshed-chats-count${query}`); return response; } catch (error) { diff --git a/src/api/fetchRewardRequestForDate.ts b/src/api/fetchRewardRequestForDate.ts deleted file mode 100644 index 94facab..0000000 --- a/src/api/fetchRewardRequestForDate.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { ethers } from "ethers"; -import dlpAbi from "../assets/contracts/dlp-abi.json"; -import { ENV_CONFIG } from "$lib/const"; -import { weiToEther } from "$lib/utils"; -import { getBlockRangeForDate, splitBlockRange } from "../lib/utils"; -import { formatDate } from "$lib/utils"; - -const provider = new ethers.JsonRpcProvider(ENV_CONFIG.VITE_RPC_URL); -const dlpContract = new ethers.Contract( - ENV_CONFIG.VITE_DLP_ADDRESS, - dlpAbi.abi, - provider -); - -export async function fetchRewardRequestForDate(date: Date) { - const formattedDate = formatDate(date, "YMD_DASH"); - const { startBlock, endBlock } = await getBlockRangeForDate(formattedDate, provider); - const blockRanges = splitBlockRange(startBlock, endBlock); - - let totalReward = 0n; // Use native BigInt for summation - let totalEvents = 0; - - for (const [fromBlock, toBlock] of blockRanges) { - const filter = dlpContract.filters.RewardRequested(); - const events = await dlpContract.queryFilter(filter, fromBlock, toBlock); - for (const event of events) { - // event.args.rewardAmount is a BigInt in ethers v6 - totalReward += (event as any).args.rewardAmount; - } - totalEvents += events.length; - } - - return { - totalReward: weiToEther(totalReward), - totalEvents - } -} diff --git a/src/api/fetchStakingEventForDate.ts b/src/api/fetchStakingEventForDate.ts deleted file mode 100644 index 2d5a1b1..0000000 --- a/src/api/fetchStakingEventForDate.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { ethers } from "ethers"; -import { ENV_CONFIG } from "$lib/const"; -import { weiToEther } from "$lib/utils"; -import { getBlockRangeForDate, splitBlockRange } from "../lib/utils"; -import { formatDate } from "$lib/utils"; -import stakingAbi from "../assets/contracts/staking-abi.json"; - -const provider = new ethers.JsonRpcProvider(ENV_CONFIG.VITE_RPC_URL); -const stakingContract = new ethers.Contract( - ENV_CONFIG.VITE_STAKING_ADDRESS, - stakingAbi.abi, - provider -); - -export async function fetchStakingEventForDate(date: Date) { - const formattedDate = formatDate(date, "YMD_DASH"); - const { startBlock, endBlock } = await getBlockRangeForDate(formattedDate, provider); - const blockRanges = splitBlockRange(startBlock, endBlock); - - let totalStake = 0n; // Use native BigInt for summation - let totalEvents = 0; - - for (const [fromBlock, toBlock] of blockRanges) { - const filter = stakingContract.filters.TokensStaked(); - const events = await stakingContract.queryFilter(filter, fromBlock, toBlock); - for (const event of events) { - // event.args.rewardAmount is a BigInt in ethers v6 - totalStake += (event as any).args.amount; - } - totalEvents += events.length; - } - - return { - totalStake: weiToEther(totalStake), - totalEvents - } -} diff --git a/src/api/fetchStakingEvents.ts b/src/api/fetchStakingEvents.ts deleted file mode 100644 index df339f9..0000000 --- a/src/api/fetchStakingEvents.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { ethers } from "ethers"; -import stakingAbi from "../assets/contracts/staking-abi.json"; -import { blockRangeForAMonth, ENV_CONFIG, maxBlockRange } from "$lib/const"; - -const provider = new ethers.JsonRpcProvider(ENV_CONFIG.VITE_RPC_URL); -const stakingContract = new ethers.Contract( - ENV_CONFIG.VITE_STAKING_ADDRESS, - stakingAbi.abi, - provider -); - -interface IFetchStakingParams { - months: number; -} - -export async function fetchStaking(params: IFetchStakingParams) { - const { months } = params; - const currentBlock = await provider.getBlockNumber(); - const startBlock = Math.max(0, currentBlock - months * blockRangeForAMonth); - - const allStakesEvents = []; - - for (let i = 0; i < months; i++) { - // Calculate block range - const fromBlock = startBlock + i * blockRangeForAMonth; - const toBlock = Math.min(fromBlock + blockRangeForAMonth, currentBlock); - - if (fromBlock >= currentBlock) { - break; - } - - const blockRanges = []; - - for (let from = fromBlock; from <= toBlock; from += maxBlockRange) { - const to = Math.min(from + maxBlockRange - 1, toBlock); - blockRanges.push({ from, to }); - } - - try { - const stakePromises = blockRanges.map(({ from, to }) => { - return stakingContract.queryFilter( - stakingContract.filters.TokensStaked(), - from, - to - ); - }); - - const stakeResults = await Promise.all(stakePromises); - - const stakeEvents = stakeResults.flat(); - - allStakesEvents.push(stakeEvents); - } catch (error) { - console.error("🚀 ~ fetchStaking ~ error:", error); - throw error; - } - - await new Promise((resolve) => setTimeout(resolve, 1000)); - } - - return allStakesEvents; -} diff --git a/src/api/fetchStakingMovement.ts b/src/api/fetchStakingMovement.ts new file mode 100644 index 0000000..b876dd8 --- /dev/null +++ b/src/api/fetchStakingMovement.ts @@ -0,0 +1,25 @@ +import { generateQuery } from "$lib/utils"; +import { httpIndexRequest, type ApiResponse } from "../lib/http/http"; + +export interface IStakeItem { + stakeamount: string, + date: string +} + +interface IStakeMovementParams { + startDate: string + endDate: string +} + +export async function fetchStakingMovement(params: IStakeMovementParams) { + const { startDate, endDate } = params; + const query = generateQuery({ startDate, endDate }); + + try { + const response: ApiResponse = await httpIndexRequest.get(`/staking-events/get-staking-movement${query}`); + + return response.data; + } catch (error) { + throw error; + } +} \ No newline at end of file diff --git a/src/api/fetchTokenEmissionMovement.ts b/src/api/fetchTokenEmissionMovement.ts new file mode 100644 index 0000000..aa06487 --- /dev/null +++ b/src/api/fetchTokenEmissionMovement.ts @@ -0,0 +1,25 @@ +import { generateQuery } from "$lib/utils"; +import { httpIndexRequest, type ApiResponse } from "../lib/http/http"; + +export interface ITokenEmissionItem { + reqrewardamount: string, + date: string +} + +interface ITokenEmissionMovementParams { + startDate: string + endDate: string +} + +export async function fetchTokenEmissionMovement(params: ITokenEmissionMovementParams) { + const { startDate, endDate } = params; + const query = generateQuery({ startDate, endDate }); + + try { + const response: ApiResponse = await httpIndexRequest.get(`/request-rewards/get-token-emission-movement${query}`); + + return response.data; + } catch (error) { + throw error; + } +} \ No newline at end of file diff --git a/src/api/fetchTokenVelocity.ts b/src/api/fetchTokenVelocity.ts new file mode 100644 index 0000000..f353594 --- /dev/null +++ b/src/api/fetchTokenVelocity.ts @@ -0,0 +1,24 @@ +import { generateQuery } from "$lib/utils"; +import { httpIndexRequest, type ApiResponse } from "../lib/http/http"; + +export interface ITokenVelocity { + tokenVelocity: string, +} + +export interface ITokenVelocityParams { + startDate: string + endDate: string +} + +export async function fetchTokenVelocity(params: ITokenVelocityParams) { + const { startDate, endDate } = params; + const query = generateQuery({ startDate, endDate }); + + try { + const response: ApiResponse = await httpIndexRequest.get(`/staking-events/token-velocity${query}`); + + return response.data; + } catch (error) { + throw error; + } +} \ No newline at end of file diff --git a/src/api/fetchTopStaker.ts b/src/api/fetchTopStaker.ts new file mode 100644 index 0000000..0937de5 --- /dev/null +++ b/src/api/fetchTopStaker.ts @@ -0,0 +1,25 @@ +import { generateQuery } from "$lib/utils"; +import { httpIndexRequest, type ApiResponse } from "../lib/http/http"; + +export interface ITopStakerItem { + wallet_address: string, + stake_amount: string +} + +export interface ITopStakersParams { + startDate: string + endDate: string +} + +export async function fetchTopStakers(params: ITopStakersParams) { + const { startDate, endDate } = params; + const query = generateQuery({ startDate, endDate }); + + try { + const response: ApiResponse = await httpIndexRequest.get(`/staking-events/top-5-stakers${query}`); + + return response.data; + } catch (error) { + throw error; + } +} \ No newline at end of file diff --git a/src/api/fetchTopUnstaker.ts b/src/api/fetchTopUnstaker.ts new file mode 100644 index 0000000..415f503 --- /dev/null +++ b/src/api/fetchTopUnstaker.ts @@ -0,0 +1,25 @@ +import { generateQuery } from "$lib/utils"; +import { httpIndexRequest, type ApiResponse } from "../lib/http/http"; + +export interface ITopUnstakerItem { + wallet_address: string, + unstake_amount: string +} + +export interface ITopUnstakersParams { + startDate: string + endDate: string +} + +export async function fetchTopUnstakers(params: ITopUnstakersParams) { + const { startDate, endDate } = params; + const query = generateQuery({ startDate, endDate }); + + try { + const response: ApiResponse = await httpIndexRequest.get(`/unstaking-events/get-top-5-unstakers${query}`); + + return response.data; + } catch (error) { + throw error; + } +} \ No newline at end of file diff --git a/src/api/fetchTotalContributorsRewardAmount.ts b/src/api/fetchTotalContributorsRewardAmount.ts deleted file mode 100644 index 6a59da6..0000000 --- a/src/api/fetchTotalContributorsRewardAmount.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { ENV_CONFIG } from "$lib/const"; -import { callRpc } from "$lib/utils"; - -export async function fetchTotalContributorsRewardAmount() { - try { - const totalContributorsRewardAmount = await callRpc( - "eth_call", - [ - { - to: ENV_CONFIG.VITE_DLP_ADDRESS, - data: "0xc41d3b63", - }, - "latest", - ], - ENV_CONFIG.VITE_RPC_URL - ); - - return Number(totalContributorsRewardAmount) / Math.pow(10, 18); - } catch (error) { - throw error; - } -} diff --git a/src/api/fetchTotalUniqueChat.ts b/src/api/fetchTotalUniqueChat.ts deleted file mode 100644 index 3d16c3b..0000000 --- a/src/api/fetchTotalUniqueChat.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { ENV_CONFIG } from "$lib/const"; -import { callRpc } from "$lib/utils"; - -export async function fetchTotalUniqueChat() { - try { - const totalUniqueChats = await callRpc( - "eth_call", - [ - { - to: ENV_CONFIG.VITE_DLP_ADDRESS, - data: "0x7ccf35a6", - }, - "latest", - ], - ENV_CONFIG.VITE_RPC_URL - ); - - return Number(totalUniqueChats); - } catch (error) { - throw error; - } -} \ No newline at end of file diff --git a/src/api/fetchTotalUniqueChatIds.ts b/src/api/fetchTotalUniqueChatIds.ts index dd84793..55c1594 100644 --- a/src/api/fetchTotalUniqueChatIds.ts +++ b/src/api/fetchTotalUniqueChatIds.ts @@ -4,7 +4,7 @@ import { http, type ApiResponse } from "../lib/http/http"; export async function fetchTotalUniqueChatIds() { try { - const response: ApiResponse = await http.get("/api/stats/total-unique-chat-ids"); + const response: ApiResponse = await http.get("/stats/total-unique-chat-ids"); return response; } catch (error) { diff --git a/src/api/fetchTotalUniqueUsers.ts b/src/api/fetchTotalUniqueUsers.ts deleted file mode 100644 index 44ae8e0..0000000 --- a/src/api/fetchTotalUniqueUsers.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { ENV_CONFIG } from "$lib/const"; -import { callRpc } from "$lib/utils"; - -export async function fetchTotalUniqueUsers() { - try { - const totalUniqueUsers = await callRpc( - "eth_call", - [ - { - to: ENV_CONFIG.VITE_DLP_ADDRESS, - data: "0x7569b3d7", - }, - "latest", - ], - ENV_CONFIG.VITE_RPC_URL - ); - - return Number(totalUniqueUsers); - } catch (error) { - throw error; - } -} \ No newline at end of file diff --git a/src/api/fetchUnstakingEvents.ts b/src/api/fetchUnstakingEvents.ts deleted file mode 100644 index 33755fa..0000000 --- a/src/api/fetchUnstakingEvents.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { ethers } from "ethers"; -import stakingAbi from "../assets/contracts/staking-abi.json"; -import { blockRangeForAMonth, ENV_CONFIG, maxBlockRange } from "$lib/const"; - -const provider = new ethers.JsonRpcProvider(ENV_CONFIG.VITE_RPC_URL); -const stakingContract = new ethers.Contract( - ENV_CONFIG.VITE_STAKING_ADDRESS, - stakingAbi.abi, - provider -); - -interface IFetchUnstakingParams { - months: number; -} - -export async function fetchUnstaking(params: IFetchUnstakingParams) { - const { months } = params; - const currentBlock = await provider.getBlockNumber(); - const startBlock = Math.max(0, currentBlock - months * blockRangeForAMonth); - - const allUnstakeEvents = []; - - for (let i = 0; i < months; i++) { - // Calculate block range - const fromBlock = startBlock + i * blockRangeForAMonth; - const toBlock = Math.min(fromBlock + blockRangeForAMonth, currentBlock); - - if (fromBlock >= currentBlock) { - break; - } - - const blockRanges = []; - - for (let from = fromBlock; from <= toBlock; from += maxBlockRange) { - const to = Math.min(from + maxBlockRange - 1, toBlock); - blockRanges.push({ from, to }); - } - - try { - const unstakePromises = blockRanges.map(({ from, to }) => - stakingContract.queryFilter( - stakingContract.filters.TokensUnstaked(), - from, - to - ) - ); - - const unstakeResults = await Promise.all(unstakePromises); - - const unstakeEvents = unstakeResults.flat(); - - allUnstakeEvents.push(unstakeEvents); - } catch (error) { - throw error; - } - - await new Promise((resolve) => setTimeout(resolve, 1000)); - } - - return allUnstakeEvents; -} diff --git a/src/api/fetchUsersByAppDaily.ts b/src/api/fetchUsersByAppDaily.ts deleted file mode 100644 index 49f008f..0000000 --- a/src/api/fetchUsersByAppDaily.ts +++ /dev/null @@ -1,22 +0,0 @@ - - -import { generateQuery } from "$lib/utils"; -import { http, type ApiResponse } from "$lib/http/http"; - -export interface IUsersByAppDailyParams { - startDate: string; - endDate: string; -} - -export async function fetchUsersByAppDaily(params: IUsersByAppDailyParams) { - const { startDate, endDate } = params; - const query = generateQuery({ startDate, endDate }); - - try { - const response: ApiResponse = await http.get(`/api/stats/users-by-app-daily${query}`); - - return response; - } catch (error) { - throw error; - } -} \ No newline at end of file diff --git a/src/api/fetchValidatorRewards.ts b/src/api/fetchValidatorRewards.ts deleted file mode 100644 index c2aeb66..0000000 --- a/src/api/fetchValidatorRewards.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { ethers } from "ethers"; -import teePoolAbi from "../assets/contracts/teepool-abi.json"; -import { blockRangeForAMonth, ENV_CONFIG, maxBlockRange } from "$lib/const"; - -const provider = new ethers.JsonRpcProvider(ENV_CONFIG.VITE_RPC_URL); -const teePoolContract = new ethers.Contract( - ENV_CONFIG.VITE_TEE_POOL_ADDRESS, - teePoolAbi.abi, - provider -); - -interface IFetchValidatorRewardsParams { - months: number; -} - -export async function fetchValidatorRewards(params: IFetchValidatorRewardsParams) { - const { months } = params; - const currentBlock = await provider.getBlockNumber(); - const startBlock = Math.max(0, currentBlock - months * blockRangeForAMonth); - - const allClaimedEvents = []; - - for (let i = 0; i < months; i++) { - // Calculate block range - const fromBlock = startBlock + i * blockRangeForAMonth; - const toBlock = Math.min(fromBlock + blockRangeForAMonth, currentBlock); - - if (fromBlock >= currentBlock) { - break; - } - - const blockRanges = []; - - for (let from = fromBlock; from <= toBlock; from += maxBlockRange) { - const to = Math.min(from + maxBlockRange - 1, toBlock); - blockRanges.push({ from, to }); - } - - try { - const claimedPromises = blockRanges.map(({ from, to }) => - teePoolContract.queryFilter( - teePoolContract.filters.Claimed(), - from, - to - ) - ); - - const claimedResults = await Promise.all(claimedPromises); - - allClaimedEvents.push(claimedResults.flat()); - } catch (error) { - throw error; - } - - await new Promise((resolve) => setTimeout(resolve, 1000)); - } - - return allClaimedEvents; -} diff --git a/src/api/subgraph-dlp.ts b/src/api/subgraph-dlp.ts index ac47bdd..5b12be5 100644 --- a/src/api/subgraph-dlp.ts +++ b/src/api/subgraph-dlp.ts @@ -1,7 +1,7 @@ import { ENV_CONFIG } from "$lib/const"; export async function fetchDlpGraph({ query = '', variables = {}, operationName = 'Subgraphs' }) { - const endpoint = `${ENV_CONFIG.VITE_DF_BASE_URL}/api/subgraph/dlp`; + const endpoint = `${ENV_CONFIG.VITE_DF_BASE_URL}/subgraph/dlp`; const response = await fetch(endpoint, { method: "POST", headers: { diff --git a/src/api/subgraph-staking.ts b/src/api/subgraph-staking.ts index 2cfce39..a893aea 100644 --- a/src/api/subgraph-staking.ts +++ b/src/api/subgraph-staking.ts @@ -30,7 +30,7 @@ export interface GraphQLData { * @returns {Promise} - The result from your backend (deserialized JSON) */ export async function fetchStakingGraph({ query = '', variables = {}, operationName = 'Subgraphs' }) { - const endpoint = `${ENV_CONFIG.VITE_DF_BASE_URL}/api/subgraph/staking`; + const endpoint = `${ENV_CONFIG.VITE_DF_BASE_URL}/subgraph/stage/staking`; const response = await fetch(endpoint, { method: "POST", headers: { @@ -39,7 +39,8 @@ export async function fetchStakingGraph({ query = '', variables = {}, operationN body: JSON.stringify({ query, variables, - operationName + operationName, + environment: 'stage' }) }); if (!response.ok) { diff --git a/src/api/subgraph-token.ts b/src/api/subgraph-token.ts index fbe30fd..ff81269 100644 --- a/src/api/subgraph-token.ts +++ b/src/api/subgraph-token.ts @@ -1,7 +1,7 @@ import { ENV_CONFIG } from "$lib/const"; export async function fetchTokenGraph({ query = '', variables = {}, operationName = 'Subgraphs' }) { - const endpoint = `${ENV_CONFIG.VITE_DF_BASE_URL}/api/subgraph/token`; + const endpoint = `${ENV_CONFIG.VITE_DF_BASE_URL}/subgraph/token`; const response = await fetch(endpoint, { method: "POST", headers: { diff --git a/src/lib/components/common/bar-chat/bar-chat.svelte b/src/lib/components/common/bar-chat/bar-chat.svelte deleted file mode 100644 index 013de9b..0000000 --- a/src/lib/components/common/bar-chat/bar-chat.svelte +++ /dev/null @@ -1,78 +0,0 @@ - - - - - {title || "Bar Chart"} - {description || "Showing data for ..."} - - - - v, - }, - yAxis: { - format: (v: number) => v.toLocaleString(), - }, - }} - > - {#snippet tooltip()} - - {/snippet} - - - - -
-
-
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
-
-
diff --git a/src/lib/components/common/bar-chat/type.ts b/src/lib/components/common/bar-chat/type.ts deleted file mode 100644 index e97e6f7..0000000 --- a/src/lib/components/common/bar-chat/type.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { SeriesData, SplineProps } from "layerchart"; -import type { ChartConfig } from "$lib/components/ui/chart/index.js"; -import type { Component } from "svelte"; - -export interface Props { - title?: string; - description?: string; - chartConfig: ChartConfig; - chartData: Record[]; - series?: SeriesData, Component>[] - className?: string; - } diff --git a/src/lib/components/common/line-chart/const.ts b/src/lib/components/common/line-chart/const.ts index 7c4b640..595bb03 100644 --- a/src/lib/components/common/line-chart/const.ts +++ b/src/lib/components/common/line-chart/const.ts @@ -19,4 +19,4 @@ export const defaultVisConfig: LineChartPropsObjProp = { format: (v: number) => formatNumberIntoShort(v), }, highlight: { points: { r: 4 } }, -} \ No newline at end of file +}; diff --git a/src/lib/components/common/line-chart/line-chart.svelte b/src/lib/components/common/line-chart/line-chart.svelte index b8d55c7..9aaed6a 100644 --- a/src/lib/components/common/line-chart/line-chart.svelte +++ b/src/lib/components/common/line-chart/line-chart.svelte @@ -5,7 +5,7 @@ import type { Props } from "./type"; import { LineChart } from "layerchart"; import Skeleton from "$lib/components/ui/skeleton/skeleton.svelte"; - import { cn } from "$lib/utils"; + import { cn, formatDecimalNumber } from "$lib/utils"; import { defaultVisConfig } from "./const"; const { @@ -15,10 +15,17 @@ className, isLoading, skeletonClass, + formatter, ...lineChartProps - }: Props = $props(); + }: Props = $props() +{#snippet defaultFormatter(tooltipProps: any)} +
+ {tooltipProps.name}: {formatDecimalNumber(tooltipProps.value)} +
+{/snippet} + {title || "Area Chart"} @@ -39,7 +46,7 @@ {...lineChartProps} > {#snippet tooltip()} - + {/snippet} diff --git a/src/lib/components/common/line-chart/type.ts b/src/lib/components/common/line-chart/type.ts index 1af028f..e9b7d3c 100644 --- a/src/lib/components/common/line-chart/type.ts +++ b/src/lib/components/common/line-chart/type.ts @@ -1,5 +1,6 @@ import type { LineChartProps } from "layerchart"; import type { ChartConfig } from "$lib/components/ui/chart/index.js"; +import type { Snippet } from "svelte"; export interface Props extends LineChartProps> { title?: string; @@ -8,4 +9,5 @@ export interface Props extends LineChartProps> { className?: string; isLoading?: boolean; skeletonClass?: string; + formatter?: Snippet; } diff --git a/src/lib/components/common/number-input/number-input.svelte b/src/lib/components/common/number-input/number-input.svelte new file mode 100644 index 0000000..f5fcb96 --- /dev/null +++ b/src/lib/components/common/number-input/number-input.svelte @@ -0,0 +1,122 @@ + + +
+ {#if label} + + {/if} + +
+ {#if leftIcon} +
+ +
+ {/if} + + + + {#if rightIcon} +
+ +
+ {/if} +
+ + {#if error} +

{error}

+ {:else if helperText} +

{helperText}

+ {/if} +
diff --git a/src/lib/components/layout/app-sidebar/data.ts b/src/lib/components/layout/app-sidebar/data.ts index e63da3e..cab1887 100644 --- a/src/lib/components/layout/app-sidebar/data.ts +++ b/src/lib/components/layout/app-sidebar/data.ts @@ -4,25 +4,31 @@ import BarChart from "@lucide/svelte/icons/bar-chart"; import Activity from "@lucide/svelte/icons/activity"; import HandCoins from "@lucide/svelte/icons/hand-coins"; import SlidersVertical from "@lucide/svelte/icons/sliders-vertical"; +import Shield from "@lucide/svelte/icons/shield"; export const data = { - user: { - name: "Dfusion", - email: "dfusion@example.com", - avatar: "/avatars/shadcn.jpg", + user: { + name: "Dfusion", + email: "dfusion@example.com", + avatar: "/avatars/shadcn.jpg", + }, + navMain: [ + { + title: "Staking Token Movement", + url: "/", + icon: BankNoteArrowUp, }, - navMain: [ - { - title: "Staking Token Movement", - url: "/staking-token-movement", - icon: BankNoteArrowUp, - }, - { - title: "Users Token Emission", - url: "/users-token-emission", - icon: BankNoteArrowUp, - }, - { + { + title: "Users Token Emission", + url: "/users-token-emission", + icon: BankNoteArrowUp, + }, + { + title: "Token Gating Settings", + url: "/token-gating-settings", + icon: Shield, + }, + { title: "$VFSN Token", url: "/token", icon: BankNoteArrowUp, @@ -32,6 +38,52 @@ export const data = { url: "/staking", icon: BankNoteArrowUp, }, + // { + // title: "User Chat Activity", + // url: "/user-chat-activity", + // icon: MessageCircleQuestion, + // }, + // { + // title: "Data Efficiency", + // url: "/data-efficiency", + // icon: BarChart, + // }, + // { + // title: "Health Subnet Ops", + // url: "/health-subnet-ops", + // icon: Activity, + // }, + // { + // title: "Pricing Monetization", + // url: "/pricing-monetization", + // icon: HandCoins, + // }, + // { + // title: "Reward Governance Control", + // url: "/reward-governance-control", + // icon: SlidersVertical, + // }, + ], + navClouds: [ + { + title: "Capture", + isActive: true, + url: "/capture", + items: [ + { + title: "Active Proposals", + url: "/capture/proposals", + }, + { + title: "Archived", + url: "/capture/archived", + }, + ], + }, + { + title: "Proposal", + url: "/proposal", + items: [ // { // title: "User Chat Activity", // url: "/user-chat-activity", @@ -60,75 +112,56 @@ export const data = { ], navClouds: [ { - title: "Capture", - isActive: true, - url: "/capture", - items: [ - { - title: "Active Proposals", - url: "/capture/proposals", - }, - { - title: "Archived", - url: "/capture/archived", - }, - ], + title: "Active Proposals", + url: "/proposal/active", }, { - title: "Proposal", - url: "/proposal", - items: [ - { - title: "Active Proposals", - url: "/proposal/active", - }, - { - title: "Archived", - url: "/proposal/archived", - }, - ], - }, - { - title: "Prompts", - url: "/prompts", - items: [ - { - title: "Active Proposals", - url: "/prompts/active", - }, - { - title: "Archived", - url: "/prompts/archived", - }, - ], - }, - ], - navSecondary: [ - { - title: "Settings", - url: "/settings", - }, - { - title: "Get Help", - url: "/help", - }, - { - title: "Search", - url: "/search", - }, - ], - documents: [ - { - name: "Data Library", - url: "/documents/library", + title: "Archived", + url: "/proposal/archived", }, + ], + }, + { + title: "Prompts", + url: "/prompts", + items: [ { - name: "Reports", - url: "/documents/reports", + title: "Active Proposals", + url: "/prompts/active", }, { - name: "Word Assistant", - url: "/documents/assistant", + title: "Archived", + url: "/prompts/archived", }, - ], -}; \ No newline at end of file + ], + }, + ], + navSecondary: [ + { + title: "Settings", + url: "/settings", + }, + { + title: "Get Help", + url: "/help", + }, + { + title: "Search", + url: "/search", + }, + ], + documents: [ + { + name: "Data Library", + url: "/documents/library", + }, + { + name: "Reports", + url: "/documents/reports", + }, + { + name: "Word Assistant", + url: "/documents/assistant", + }, + ], +}; diff --git a/src/lib/components/layout/nav-main/nav-main.svelte b/src/lib/components/layout/nav-main/nav-main.svelte index f7bba16..235ae71 100644 --- a/src/lib/components/layout/nav-main/nav-main.svelte +++ b/src/lib/components/layout/nav-main/nav-main.svelte @@ -1,5 +1,6 @@ + +
+
+
+

+ 404 +

+

+ Oops, the page you are looking for could not be found. +

+
+ +
+
+
+
diff --git a/src/routes/staking-token-movement/components/staking-movement-chart-month/staking-movement-chart-month.svelte b/src/routes/staking-token-movement/components/staking-movement-chart-month/staking-movement-chart-month.svelte index 9921f8d..4201cff 100644 --- a/src/routes/staking-token-movement/components/staking-movement-chart-month/staking-movement-chart-month.svelte +++ b/src/routes/staking-token-movement/components/staking-movement-chart-month/staking-movement-chart-month.svelte @@ -1,140 +1,132 @@
-
- Data shown 30 days back from - - - -
- -
- - - -
+
+ Data shown 30 days back from + + + +
+ +
+ + + +
diff --git a/src/routes/staking-token-movement/components/staking-movement-chart-week/staking-movement-chart-week.svelte b/src/routes/staking-token-movement/components/staking-movement-chart-week/staking-movement-chart-week.svelte index 00d700a..dc77a94 100644 --- a/src/routes/staking-token-movement/components/staking-movement-chart-week/staking-movement-chart-week.svelte +++ b/src/routes/staking-token-movement/components/staking-movement-chart-week/staking-movement-chart-week.svelte @@ -1,18 +1,19 @@
- - + + - +
diff --git a/src/routes/staking-token-movement/components/statistic-grid/token-velocity.svelte b/src/routes/staking-token-movement/components/statistic-grid/token-velocity.svelte index 448c2c1..a20e8fc 100644 --- a/src/routes/staking-token-movement/components/statistic-grid/token-velocity.svelte +++ b/src/routes/staking-token-movement/components/statistic-grid/token-velocity.svelte @@ -1,23 +1,40 @@ @@ -33,7 +50,7 @@
@@ -83,18 +107,18 @@ })} > - {member.address} + {member.wallet_address}
Address -

{member.address}

+

{member.wallet_address}

Amount

{formatDecimalNumber( - Number(member.amount) + Number(member.stake_amount) )} {tokenSymbol}

@@ -125,18 +149,18 @@ })} > - {member.address} + {member.wallet_address}
Address -

{member.address}

+

{member.wallet_address}

Amount

{formatDecimalNumber( - Number(member.amount) + Number(member.unstake_amount) )} {tokenSymbol}

diff --git a/src/routes/staking-token-movement/const.ts b/src/routes/staking-token-movement/const.ts index 827ee54..b47d6f2 100644 --- a/src/routes/staking-token-movement/const.ts +++ b/src/routes/staking-token-movement/const.ts @@ -37,4 +37,4 @@ export const monthVisConfig: LineChartPropsObjProp = { }, ticks: 30, }, -}; \ No newline at end of file +}; diff --git a/src/routes/staking-token-movement/utils.ts b/src/routes/staking-token-movement/utils.ts deleted file mode 100644 index 428db7e..0000000 --- a/src/routes/staking-token-movement/utils.ts +++ /dev/null @@ -1,219 +0,0 @@ -import type { ethers } from "ethers"; -import { formatNumberWithDecimals } from "$lib/utils"; -import { weiToEther } from "../../lib/utils"; -import { blockRangeForADay, queryMonthDuration, daysPerMonth, weeksPerMonth } from "$lib/const"; - -export const calculateTotalFromEvents = ( - events: (ethers.Log | ethers.EventLog)[] -): number => { - return events.reduce((total, event) => { - const eventLog = event as any; - const amount = weiToEther(eventLog.args?.[1]); - return total + amount; - }, 0); -}; - -export const calculateStakeAmount = ( - stakeEvents: (ethers.Log | ethers.EventLog)[][] -) => { - return stakeEvents.map(calculateTotalFromEvents); -}; - -export const calculateNetFlowInfo = ( - stakeEvents: (ethers.Log | ethers.EventLog)[][], - unstakeEvents: (ethers.Log | ethers.EventLog)[][] -): { - netFlow: string; - netFlowPerDay: string; - netFlowPerWeek: string; - totalStakeIn: string; - totalUnstakeOut: string; -} => { - if (!stakeEvents || !unstakeEvents) { - return { - netFlow: "", - netFlowPerDay: "", - netFlowPerWeek: "", - totalStakeIn: "", - totalUnstakeOut: "", - }; - } - - // Single flat operation for better performance - const flatStakeEvents = stakeEvents.flat(); - const flatUnstakeEvents = unstakeEvents.flat(); - - // Use reduce for O(n) calculation instead of multiple operations - const totalStakeIn = calculateTotalFromEvents(flatStakeEvents); - - const totalUnstakeOut = calculateTotalFromEvents(flatUnstakeEvents); - - // Calculate net flow - const netFlow = totalStakeIn - totalUnstakeOut; - - // Calculate per day (assuming 6 months = 180 days) - const daysInPeriod = daysPerMonth * queryMonthDuration; - const netFlowPerDay = netFlow / daysInPeriod; - - // Calculate per week - const weeksInPeriod = weeksPerMonth * queryMonthDuration; - const netFlowPerWeek = netFlow / weeksInPeriod; - - return { - netFlow: formatNumberWithDecimals(netFlow), - netFlowPerDay: formatNumberWithDecimals(netFlowPerDay), - netFlowPerWeek: formatNumberWithDecimals(netFlowPerWeek), - totalStakeIn: formatNumberWithDecimals(totalStakeIn), - totalUnstakeOut: formatNumberWithDecimals(totalUnstakeOut), - }; -}; - -export const getTopStakers = ( - stakeEvents: (ethers.Log | ethers.EventLog)[][], - unstakeEvents: (ethers.Log | ethers.EventLog)[][] -) => { - if (!stakeEvents || !unstakeEvents) return; - - try { - // Single flat operation for better performance - const flatStakeEvents = stakeEvents.flat(); - const flatUnstakeEvents = unstakeEvents.flat(); - - // Use Maps for O(1) lookups instead of Sets and filters - const stakerAmounts = new Map(); - const withdrawerAmounts = new Map(); - - // Process stake events in single pass - O(n) - flatStakeEvents.forEach((event) => { - const address = (event as any).args[0]; - const amount = weiToEther((event as any).args[1]); - - const currentAmount = stakerAmounts.get(address) || 0; - stakerAmounts.set(address, currentAmount + amount); - }); - - // Process unstake events in single pass - O(n) - flatUnstakeEvents.forEach((event) => { - const address = (event as any).args[0]; - const amount = weiToEther((event as any).args[1]); - - const currentAmount = withdrawerAmounts.get(address) || 0; - withdrawerAmounts.set(address, currentAmount + amount); - }); - - // Sort and get top 5 stakers - O(n log n) but n is small (unique addresses) - const top5Stakers = Array.from(stakerAmounts.entries()) - .sort(([, a], [, b]) => b - a) - .slice(0, 5) - .map(([address, amount]) => ({ - address, - amount: amount.toFixed(2), - })); - - // Sort and get top 5 withdrawers - O(n log n) but n is small - const top5Withdrawers = Array.from(withdrawerAmounts.entries()) - .sort(([, a], [, b]) => b - a) - .slice(0, 5) - .map(([address, amount]) => ({ - address, - amount: amount.toFixed(2), - })); - - return { - top5Stakers, - top5Withdrawers, - }; - } catch (error) { - throw error; - } -}; - -export const getTokenVelocity = ( - stakeEvents: (ethers.Log | ethers.EventLog)[][], - unstakeEvents: (ethers.Log | ethers.EventLog)[][] -) => { - if (!stakeEvents || !unstakeEvents) return; - - try { - // Flatten events once - O(n) - const flatStakeEvents = stakeEvents.flat(); - const flatUnstakeEvents = unstakeEvents.flat(); - - // Create Maps for O(1) lookups instead of Sets and filters - O(n) - const stakeAddressMap = new Map>(); - const unstakeAddressMap = new Map>(); - - // Process stake events - O(n) - flatStakeEvents.forEach((event) => { - const address = (event as any).args[0]; - const blockNumber = Number((event as any).blockNumber); - const amount = weiToEther((event as any).args[1]); - - if (!stakeAddressMap.has(address)) { - stakeAddressMap.set(address, []); - } - stakeAddressMap.get(address)!.push({ blockNumber, amount }); - }); - - // Process unstake events - O(n) - flatUnstakeEvents.forEach((event) => { - const address = (event as any).args[0]; - const blockNumber = Number((event as any).blockNumber); - const amount = weiToEther((event as any).args[1]); - - if (!unstakeAddressMap.has(address)) { - unstakeAddressMap.set(address, []); - } - unstakeAddressMap.get(address)!.push({ blockNumber, amount }); - }); - - // Find addresses with both stake and unstake events - O(n) - const addressesWithBoth = Array.from(stakeAddressMap.keys()).filter(addr => - unstakeAddressMap.has(addr) - ); - - // Calculate hold durations - O(n) - const holdDurations: number[] = []; - - addressesWithBoth.forEach((address) => { - const stakeEvents = stakeAddressMap.get(address)!.sort((a, b) => a.blockNumber - b.blockNumber); - const unstakeEvents = unstakeAddressMap.get(address)!.sort((a, b) => a.blockNumber - b.blockNumber); - - // Use two pointers for O(n) matching instead of nested loops - let stakeIndex = 0; - let unstakeIndex = 0; - - while (stakeIndex < stakeEvents.length && unstakeIndex < unstakeEvents.length) { - const stake = stakeEvents[stakeIndex]; - const unstake = unstakeEvents[unstakeIndex]; - - if (unstake.blockNumber > stake.blockNumber && - Math.abs(unstake.amount - stake.amount) < 0.000001) { - // Found matching pair - const holdTime = unstake.blockNumber - stake.blockNumber; - holdDurations.push(holdTime); - stakeIndex++; - unstakeIndex++; - } else if (unstake.blockNumber <= stake.blockNumber) { - unstakeIndex++; - } else { - stakeIndex++; - } - } - }); - - // Calculate average - O(n) - const averageHoldDuration = holdDurations.length > 0 - ? holdDurations.reduce((sum, duration) => sum + duration, 0) / holdDurations.length - : 0; - - // Convert to days (assuming 6 second block time) - const blocksPerDay = blockRangeForADay; // 24 * 60 * 60 / 6 - const averageHoldDays = averageHoldDuration / blocksPerDay; - const tokenVelocity = averageHoldDays.toFixed(2); - - return tokenVelocity; - } catch (error) { - throw error; - } -}; diff --git a/src/routes/staking/+page.svelte b/src/routes/staking/+page.svelte index 708aa13..3c0767f 100644 --- a/src/routes/staking/+page.svelte +++ b/src/routes/staking/+page.svelte @@ -1,6 +1,7 @@ -
- +
+
+ +
+ +
+ +
diff --git a/src/routes/staking/components/staking-movement-chart.svelte b/src/routes/staking/components/staking-movement-chart.svelte index c4a06c2..c2686ce 100644 --- a/src/routes/staking/components/staking-movement-chart.svelte +++ b/src/routes/staking/components/staking-movement-chart.svelte @@ -1,10 +1,11 @@
- +
diff --git a/src/routes/staking/components/staking-movement.svelte b/src/routes/staking/components/staking-movement.svelte index 26b1323..73812bd 100644 --- a/src/routes/staking/components/staking-movement.svelte +++ b/src/routes/staking/components/staking-movement.svelte @@ -1,6 +1,5 @@ + + +
+ +
+ Total Currently Staked +
+
+ +
+ + {#if loading} +
+ +
+ {:else} +
+ Balance: + {generateTokenText(balance)} +
+ {/if} +
+
diff --git a/src/routes/token-gating/+page.svelte b/src/routes/token-gating/+page.svelte new file mode 100644 index 0000000..6faec98 --- /dev/null +++ b/src/routes/token-gating/+page.svelte @@ -0,0 +1,19 @@ + + +
+
+
+ +

Token Gating Configuration

+
+

Configure the minimum token requirements for accessing protected content and features.

+
+ + + + +
diff --git a/src/routes/token-gating/components/token-gating-config/token-gating-config.svelte b/src/routes/token-gating/components/token-gating-config/token-gating-config.svelte new file mode 100644 index 0000000..fe6f6f0 --- /dev/null +++ b/src/routes/token-gating/components/token-gating-config/token-gating-config.svelte @@ -0,0 +1,209 @@ + + + + + + + Access Requirements + + Set the minimum thresholds users must meet to gain access. Users must satisfy BOTH conditions. + + +
+
+ + + Current: {formatValue(initialConfig.stakeThreshold)} + +
+
+ { + stakeThreshold = (e.target as HTMLInputElement).value; + stakeThresholdError = ""; + }} + onChange={(e: Event) => { + stakeThreshold = (e.target as HTMLInputElement).value; + stakeThresholdError = ""; + }} + /> +
+

+ + Minimum number of tokens that must be actively staked in the protocol to gain access. +

+
+ + + +
+
+ + + Current: {formatValue(initialConfig.balanceThreshold)} + +
+
+ { + balanceThreshold = (e.target as HTMLInputElement).value; + balanceThresholdError = ""; + }} + onChange={(e: Event) => { + balanceThreshold = (e.target as HTMLInputElement).value; + balanceThresholdError = ""; + }} + /> +
+

+ + Minimum token balance that must be held in the user's wallet to gain access. +

+
+ +
+

Access Requirements Preview

+
+
+ Minimum Staked: + {stakeThreshold || "0"} tokens +
+
+ Minimum Balance: + {balanceThreshold || "0"} tokens +
+
+
+ +
+
+ +
+
+
+
diff --git a/src/routes/token-gating/components/token-gating-description/token-gating-description.svelte b/src/routes/token-gating/components/token-gating-description/token-gating-description.svelte new file mode 100644 index 0000000..d731553 --- /dev/null +++ b/src/routes/token-gating/components/token-gating-description/token-gating-description.svelte @@ -0,0 +1,42 @@ + + + + + How Token Gating Works + + +
+
+ 1 +
+
+

Stake Verification

+

System checks if the user has staked the minimum required tokens in the protocol.

+
+
+
+
+ 2 +
+
+

Balance Verification

+

System verifies the user's wallet contains the minimum token balance.

+
+
+
+
+ +
+
+

Access Granted

+

If both conditions are met, the user gains access to protected features.

+
+
+
+
diff --git a/src/routes/user-chat-activity/+page.svelte b/src/routes/user-chat-activity/+page.svelte index f5f46ce..63e35ec 100644 --- a/src/routes/user-chat-activity/+page.svelte +++ b/src/routes/user-chat-activity/+page.svelte @@ -2,53 +2,9 @@ import * as Card from "$lib/components/ui/card/index.js"; import { Skeleton } from "$lib/components/ui/skeleton/index.js"; import { formatNumberIntoShort } from "$lib/utils"; - import { onMount } from "svelte"; - import { fetchTotalUniqueUsers } from "../../api/fetchTotalUniqueUsers"; - import { fetchTotalContributorsRewardAmount } from "../../api/fetchTotalContributorsRewardAmount"; import { metrics } from "./const"; - import { ENV_CONFIG } from "$lib/const"; - import { ethers } from "ethers"; - import teepoolAbi from "../../assets/contracts/teepool-abi.json"; - import { fetchChatInfo } from "../../api/fetchChatInfo"; - - const provider = new ethers.JsonRpcProvider(ENV_CONFIG.VITE_RPC_URL); - - const teepoolContract = new ethers.Contract( - ENV_CONFIG.VITE_TEE_POOL_ADDRESS, - teepoolAbi.abi, - provider - ); let isLoading = $state(false); - - onMount(async () => { - try { - isLoading = true; - const totalUniqueUsers = await fetchTotalUniqueUsers(); - const chatInfo = await fetchChatInfo(); - const totalUniqueChats = chatInfo.data.totalChats; - const totalContributorsRewardAmount = - await fetchTotalContributorsRewardAmount(); - const totalUniqueChatsPerUser = Math.floor( - totalUniqueChats / totalUniqueUsers - ); - const averageVFSNPerHolder = - totalContributorsRewardAmount / totalUniqueUsers; - const averageRewardsPerChat = - totalContributorsRewardAmount / totalUniqueChats; - - metrics[0].value = totalUniqueUsers; - metrics[1].value = totalUniqueChats; //total unique chats - metrics[2].value = totalUniqueChatsPerUser; - metrics[8].value = averageVFSNPerHolder; - metrics[9].value = totalContributorsRewardAmount; - metrics[10].value = averageRewardsPerChat; - } catch (error) { - throw error; - } finally { - isLoading = false; - } - });
diff --git a/src/routes/users-token-emission/components/chat-stats/chat-stats.svelte b/src/routes/users-token-emission/components/chat-stats/chat-stats.svelte index 12ec1e9..7bbce98 100644 --- a/src/routes/users-token-emission/components/chat-stats/chat-stats.svelte +++ b/src/routes/users-token-emission/components/chat-stats/chat-stats.svelte @@ -1,5 +1,5 @@ @@ -132,7 +123,7 @@ diff --git a/src/routes/users-token-emission/components/token-emission-chart-week/token-emission-chart-week.svelte b/src/routes/users-token-emission/components/token-emission-chart-week/token-emission-chart-week.svelte index 780433c..de46a1b 100644 --- a/src/routes/users-token-emission/components/token-emission-chart-week/token-emission-chart-week.svelte +++ b/src/routes/users-token-emission/components/token-emission-chart-week/token-emission-chart-week.svelte @@ -5,59 +5,46 @@ tokenEmissionStore, } from "$lib/stores/tokenEmissionStore"; import { onMount } from "svelte"; - import { generateDailyChartData } from "$lib/utils"; - import { fromIndex, lastWeekDayInx } from "$lib/const"; + import { formatDate, generateDailyChartData } from "$lib/utils"; + import { fromIndex, daysPerWeek } from "$lib/const"; import Button from "$lib/components/ui/button/button.svelte"; import { RefreshCwIcon } from "@lucide/svelte"; - import { fetchRewardRequestForDate } from "../../../../api/fetchRewardRequestForDate"; + import { toast } from "svelte-sonner"; + import { fetchStakingMovement } from "../../../../api/fetchStakingMovement"; import { ChartConfig, series, weekVisConfig } from "../../const"; - let chartData = $state(generateDailyChartData(fromIndex, lastWeekDayInx)); + let chartData = $state(generateDailyChartData(fromIndex, daysPerWeek)); let isLoading = $state(false); const store = $tokenEmissionStore; const fetchData = async () => { - let chartWeekData = generateDailyChartData(fromIndex, lastWeekDayInx); - try { isLoading = true; - - const mid = Math.ceil(chartWeekData.length / 2); - - const [firstHalf, secondHalf] = [ - chartWeekData.slice(0, mid), - chartWeekData.slice(mid), - ]; - - const promises = firstHalf.map((item) => - fetchRewardRequestForDate(item.date) - ); - - const weekData = await Promise.all(promises); - - const nextPromises = secondHalf.map((item) => - fetchRewardRequestForDate(item.date) + const today = new Date(); + const daysBack7 = new Date( + new Date().setDate(new Date().getDate() - daysPerWeek), ); - const nextWeekData = await Promise.all(nextPromises); - - const mergedWeekData = [...weekData, ...nextWeekData]; - - chartWeekData = chartWeekData.map((item, index) => ({ - ...item, - amount: mergedWeekData[index].totalReward || 0, - })); - - chartData = chartWeekData; - tokenEmissionActions.setRewardOnWeek(chartWeekData); - } catch (error) { - chartData = chartWeekData; - throw error; + const params = { + startDate: formatDate(daysBack7, "YMD_DASH"), + endDate: formatDate(today, "YMD_DASH"), + }; + + const response = await fetchStakingMovement(params); + + chartData = response?.map((item, index) => { + return { + date: chartData[index].date, + amount: Number(item.stakeamount), + }; + }); + tokenEmissionActions.setRewardOnWeek(chartData); + } catch (err) { + toast.error("Fetching week token emission movement Failed!"); } finally { isLoading = false; - tokenEmissionActions.setLoading(false); } }; @@ -85,7 +72,7 @@ diff --git a/src/routes/users-token-emission/utils.ts b/src/routes/users-token-emission/utils.ts index 0d4ff31..2c0ae49 100644 --- a/src/routes/users-token-emission/utils.ts +++ b/src/routes/users-token-emission/utils.ts @@ -1,26 +1,16 @@ -import { daysPerMonth } from "$lib/const"; -import { formatDate, formatDecimalNumber, formatNumberIntoShort, generateDailyChartData } from "../../lib/utils"; +import { formatDate, formatDecimalNumber } from "../../lib/utils"; + +interface IChatItem { + date: Date; + newChats: number; + refreshedChats: number; +} export const generateValueString = (value: string) => { if (!value) return "-"; return formatDecimalNumber(Number(value)); }; -export const getDateParams = (selectedDateIndex: number) => { - const monthData = generateDailyChartData( - selectedDateIndex, - selectedDateIndex + daysPerMonth - ); - - const params = { - startDate: formatDate(monthData[0].date, "YMD_DASH"), - endDate: formatDate(monthData[monthData.length - 1].date, "YMD_DASH"), - }; - - return params -}; - - export const generateChatStatsData = (from: number, to: number) => { const data = []; const now = new Date(); @@ -37,18 +27,15 @@ export const generateChatStatsData = (from: number, to: number) => { return data; }; -export const generateChatStatsParams = (from: number, to: number) => { - const weekData = generateChatStatsData(from, to); - - const params: { startDate: string, endDate: string }[] = []; +export const generateChatStatsParams = (chatStatsData: IChatItem[]) => { + const params: { startDate: string; endDate: string }[] = []; - for (let i = 0; i < weekData.length - 1; i++) { - const startDate = formatDate(weekData[i].date, "YMD_DASH"); - const endDate = formatDate(weekData[i + 1].date, "YMD_DASH"); + for (let i = 0; i < chatStatsData.length - 1; i++) { + const startDate = formatDate(chatStatsData[i].date, "YMD_DASH"); + const endDate = formatDate(chatStatsData[i + 1].date, "YMD_DASH"); params.push({ startDate, endDate }); } return params; -} - +}; diff --git a/src/routes/vfsn-token/components/vfsn-token-emission.svelte b/src/routes/vfsn-token/components/vfsn-token-emission.svelte index f45495c..934bc3e 100644 --- a/src/routes/vfsn-token/components/vfsn-token-emission.svelte +++ b/src/routes/vfsn-token/components/vfsn-token-emission.svelte @@ -36,7 +36,7 @@ const currentDate = new Date(); const thirtyDaysAgo = new Date(currentDate); - thirtyDaysAgo.setDate(currentDate.getDate() - (Number(daysFilter) - 1)); + thirtyDaysAgo.setDate(currentDate.getDate() - (Number(daysFilter))); thirtyDaysAgo.setHours(0, 0, 0, 0); const startOfNDaysAgo = thirtyDaysAgo.getTime(); currentDate.setHours(23, 59, 59, 0); @@ -68,12 +68,10 @@ rewardAmount: parseFloat(item.totalRewardAmount) / 1e18, })); - // stakeEventsActions.setStakeOnWeek(chartData); } catch (error) { console.error("Error fetching staking metrics:", error); } finally { isLoading = false; - stakeEventsActions.setLoading(false); } };