From f1a7f4596710173e98db34a763e3a5d93d297c6f Mon Sep 17 00:00:00 2001 From: geovgy <54918343+geovgy@users.noreply.github.com> Date: Sat, 20 Sep 2025 20:58:01 -0400 Subject: [PATCH] Apply shell subgraph changes --- frontend/app/src/app/api/leaderboard/data.ts | 107 -- .../app/src/app/api/leaderboard/mock-data.ts | 164 -- frontend/app/src/app/api/leaderboard/route.ts | 26 - frontend/app/src/app/shells/page.tsx | 253 +-- frontend/app/src/env.ts | 3 - frontend/app/src/shell-graphql/gql.ts | 6 + frontend/app/src/shell-graphql/graphql.ts | 1387 ++++++++++++++++- frontend/app/src/shell-hooks.ts | 60 +- frontend/app/src/shell-queries.ts | 11 + frontend/app/src/shellpoints/lib/index.ts | 175 --- frontend/app/src/shellpoints/lib/troves.ts | 11 +- frontend/app/src/subgraph-queries.ts | 31 +- 12 files changed, 1594 insertions(+), 640 deletions(-) delete mode 100644 frontend/app/src/app/api/leaderboard/data.ts delete mode 100644 frontend/app/src/app/api/leaderboard/mock-data.ts delete mode 100644 frontend/app/src/app/api/leaderboard/route.ts delete mode 100644 frontend/app/src/shellpoints/lib/index.ts diff --git a/frontend/app/src/app/api/leaderboard/data.ts b/frontend/app/src/app/api/leaderboard/data.ts deleted file mode 100644 index 1b9a3bff4..000000000 --- a/frontend/app/src/app/api/leaderboard/data.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { queryShellpointsAndActivity } from "@/src/shellpoints/lib"; -import { formatUnits, getAddress, isAddressEqual, type Address } from "viem"; -import type { LeaderboardEntry, LeaderboardActivity, LeaderboardData } from "@/src/shellpoints/leaderboard"; -import { ALCHEMY_API_KEY, GRAPH_TOKEN_API_TOKEN } from "@/src/shellpoints/utils/env"; -import { getMainnetPublicClient } from "@/src/shellpoints/utils/client"; -import { getEnsName } from "viem/ens"; -// import { NULL_ADDRESS } from "@/src/shellpoints/utils/constants"; - -export function getLeaderboardActivityName(activity: LeaderboardActivity): string { - switch (activity) { - case "yusnd": - return "yUSND"; - case "balancer": - return "Balancer"; - case "bunni": - return "Bunni"; - case "camelot": - return "Camelot"; - case "spectra": - return "Spectra"; - case "goSlowNft": - return "GoSlow NFT"; - case "trove": - return "Borrowing"; - case "stabilityPool": - return "Stability Pool"; - default: - throw new Error(`Unknown leaderboard activity: ${activity}`); - } -} - -export async function getLeaderboardData(): Promise { - const alchemyApiKey = ALCHEMY_API_KEY; - if (!alchemyApiKey) { - throw new Error("ALCHEMY_API_KEY is not set"); - } - - const graphTokenApiToken = GRAPH_TOKEN_API_TOKEN; - if (!graphTokenApiToken) { - throw new Error("GRAPH_TOKEN_API_TOKEN is not set"); - } - - const users = await queryShellpointsAndActivity(); - - let lastMintBlock = 0n; - const client = getMainnetPublicClient(); - - const shellpoints: Omit[] = await Promise.all(users.shellPoints.map(async (user) => { - const ensName = (await getEnsName(client, { address: user.holder })) ?? null; - return { - address: user.holder, - ensName, - // ensName: null, - shellpoints: { - total: Number(formatUnits(user.balance!, 18)), - mostRecent: null, - }, - activities: getLeaderboardActivities(users, user.holder).map(activity => getLeaderboardActivityName(activity)), - } - // return { - // address: user.address, - // // ensName: await getEnsName(client, { address: user.holder }), - // ensName: null, - // shellpoints: { - // total: Number(formatUnits(user.amount, user.decimals)), - // mostRecent: null, - // }, - // activities: getLeaderboardActivities(users, user.address).map(activity => getLeaderboardActivityName(activity)), - // } - })); - - return { - entries: shellpoints - .sort((a, b) => b.shellpoints.total - a.shellpoints.total) - .map((entry, index) => ({ - ...entry, - shellpoints: { - total: Math.round(entry.shellpoints.total), - mostRecent: entry.shellpoints.mostRecent, - }, - rank: index + 1 - })) - .filter((entry) => entry.shellpoints.total > 0), - lastMintBlock: { - blockNumber: Number(lastMintBlock), - // blockTimestamp: Number((await client.getBlock({ blockNumber: lastMintBlock })).timestamp) - blockTimestamp: 0, - } - } -} - -function getLeaderboardActivities(users: Awaited>, address: Address): LeaderboardActivity[] { - const activities: LeaderboardActivity[] = []; - - if (users.activities.yusnd.some(user => isAddressEqual(user.address, address))) activities.push("yusnd"); - if (users.activities.balancer.some(user => isAddressEqual(user.address, address))) activities.push("balancer"); - if (users.activities.bunni.some(user => isAddressEqual(user.address, address))) activities.push("bunni"); - if (users.activities.camelot.some(user => isAddressEqual(user.address, address))) activities.push("camelot"); - if (users.activities.spectra.some(user => isAddressEqual(user.address, address))) activities.push("spectra"); - if (users.activities.goSlowNft.some(user => isAddressEqual(user.holder, address))) activities.push("goSlowNft"); - if (users.activities.troves.some(trove => isAddressEqual(getAddress(trove.borrower), address))) activities.push("trove"); - if (Object.keys(users.activities.stabilityPoolDeposits).some(depositor => isAddressEqual(getAddress(depositor), address))) activities.push("stabilityPool"); - - if (activities.length === 0) activities.push("trove"); // Assume they have a trove not included in subgraph query limit if no other activity - - return activities; -} \ No newline at end of file diff --git a/frontend/app/src/app/api/leaderboard/mock-data.ts b/frontend/app/src/app/api/leaderboard/mock-data.ts deleted file mode 100644 index 604e0376f..000000000 --- a/frontend/app/src/app/api/leaderboard/mock-data.ts +++ /dev/null @@ -1,164 +0,0 @@ -import { type Address } from "viem"; -import type { LeaderboardData, LeaderboardEntry } from "@/src/shellpoints/leaderboard"; -// import { getPublicClient } from "@/src/shellpoints/utils/client"; -// import { ORIGIN_BLOCK } from "@/src/shellpoints/utils/constants"; - -// Mock calculation function - replace with actual backend integration -export async function getMockLeaderboardData(): Promise { - // const client = getPublicClient(); - - // const originBlock = await client.getBlock({ blockNumber: ORIGIN_BLOCK }); - // const originTimestamp = Number(originBlock.timestamp); - - // function getRandomTimestamp(min: number, max: number) { - // return Math.floor(Math.random() * (max - min + 1)) + min; - // } - - // This would normally call your backend services to get real data - const mockData: Omit[] = [ - { - address: '0x1234567890123456789012345678901234567890' as Address, - ensName: "mockuser.eth", - shellpoints: { - total: 15420, - mostRecent: { - amount: 15420, - blockNumber: 17332323, - // blockTimestamp: Date.now() / 1000 - } - }, - activities: ['Borrowing', 'Stability Pool', 'YUSND Holding'] - }, - { - address: '0x2345678901234567890123456789012345678901' as Address, - ensName: "mockuser2.eth", - shellpoints: { - total: 12350, - mostRecent: { - amount: 12350, - blockNumber: 17332323, - // blockTimestamp: Date.now() / 1000 - } - }, - activities: ['GoSlow NFT', 'Camelot LP', 'Bunni LP'] - }, - { - address: '0x3456789012345678901234567890123456789012' as Address, - ensName: null, - shellpoints: { - total: 10100, - mostRecent: { - amount: 10100, - blockNumber: 17332323, - // blockTimestamp: getRandomTimestamp(originTimestamp, Date.now()) - } - }, - activities: ['Stability Pool', 'Spectra Supply'] - }, - { - address: '0x4567890123456789012345678901234567890123' as Address, - ensName: null, - shellpoints: { - total: 8750, - mostRecent: { - amount: 8750, - blockNumber: 17332323, - // blockTimestamp: getRandomTimestamp(originTimestamp, Date.now() / 1000) - } - }, - activities: ['Borrowing', 'YUSND Holding'] - }, - { - address: '0x5678901234567890123456789012345678901234' as Address, - ensName: null, - shellpoints: { - total: 7200, - mostRecent: { - amount: 7200, - blockNumber: 17332323, - // blockTimestamp: getRandomTimestamp(originTimestamp, Date.now() / 1000) - } - }, - activities: ['Camelot LP', 'Stability Pool'] - }, - { - address: '0x6789012345678901234567890123456789012345' as Address, - ensName: null, - shellpoints: { - total: 6850, - mostRecent: { - amount: 6850, - blockNumber: 17332323, - // blockTimestamp: getRandomTimestamp(originTimestamp, Date.now() / 1000) - } - }, - activities: ['GoSlow NFT', 'Borrowing'] - }, - { - address: '0x7890123456789012345678901234567890123456' as Address, - ensName: null, - shellpoints: { - total: 5500, - mostRecent: { - amount: 5500, - blockNumber: 17332320, - // blockTimestamp: getRandomTimestamp(originTimestamp, Date.now() / 1000) - } - }, - activities: ['Bunni LP', 'YUSND Holding'] - }, - { - address: '0x8901234567890123456789012345678901234567' as Address, - ensName: null, - shellpoints: { - total: 4200, - mostRecent: { - amount: 4200, - blockNumber: 17332323, - // blockTimestamp: getRandomTimestamp(originTimestamp, Date.now() / 1000) - } - }, - activities: ['Stability Pool'] - }, - { - address: '0x9012345678901234567890123456789012345678' as Address, - ensName: null, - shellpoints: { - total: 3800, - mostRecent: { - amount: 3800, - blockNumber: 17332323, - // blockTimestamp: getRandomTimestamp(originTimestamp, Date.now() / 1000) - } - }, - activities: ['Spectra Supply', 'Borrowing'] - }, - { - address: '0xa123456789012345678901234567890123456789' as Address, - ensName: null, - shellpoints: { - total: 2500, - mostRecent: { - amount: 2500, - blockNumber: 17332320, - // blockTimestamp: getRandomTimestamp(originTimestamp, Date.now() / 1000) - } - }, - activities: ['YUSND Holding'] - } - ]; - - // Sort by shellpoints descending and add ranks - return { - entries: mockData - .sort((a, b) => b.shellpoints.total - a.shellpoints.total) - .map((entry, index) => ({ - ...entry, - rank: index + 1 - })), - lastMintBlock: { - blockNumber: 17332323, - blockTimestamp: Date.now() / 1000 - } - } -} \ No newline at end of file diff --git a/frontend/app/src/app/api/leaderboard/route.ts b/frontend/app/src/app/api/leaderboard/route.ts deleted file mode 100644 index 2acfb413a..000000000 --- a/frontend/app/src/app/api/leaderboard/route.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { NextResponse } from 'next/server'; -// import { getLeaderboardData } from './data'; -// import { getMockLeaderboardData } from './mock-data'; -// import { DEMO_MODE } from '@/src/shellpoints/utils/env'; - - -export async function GET() { - try { - // const leaderboardData = DEMO_MODE ? - // await getMockLeaderboardData() - // : await getLeaderboardData(); - - // return NextResponse.json({ - // success: true, - // data: leaderboardData, - // lastUpdated: new Date(leaderboardData.lastMintBlock.blockTimestamp * 1000).toISOString() - // }); - throw new Error('Not implemented'); - } catch (error) { - // console.error('Error fetching leaderboard data:', error); - return NextResponse.json( - { success: false, error: 'Failed to fetch leaderboard data' }, - { status: 500 } - ); - } -} \ No newline at end of file diff --git a/frontend/app/src/app/shells/page.tsx b/frontend/app/src/app/shells/page.tsx index a5ed31bca..69ca9c5ca 100644 --- a/frontend/app/src/app/shells/page.tsx +++ b/frontend/app/src/app/shells/page.tsx @@ -4,71 +4,71 @@ import { useMemo, useState } from 'react'; import { getSnailIcon } from '@/src/comps/SnailIcons/snail-icons'; import { css, cx } from '@/styled-system/css'; import { LinkTextButton } from '@/src/comps/LinkTextButton/LinkTextButton'; -import { useShellActivitiesOfHolders, useShellBalances } from '@/src/shell-hooks'; +import { useAllocations, useShellBalances } from '@/src/shell-hooks'; import { Address, formatUnits, getAddress, isAddressEqual } from 'viem'; -import { CONTRACT_ADDRESSES } from '@/src/contracts'; +// import { CONTRACT_ADDRESSES } from '@/src/contracts'; import { useQuery } from '@tanstack/react-query'; -import { CollIndex } from '@/src/types'; -import { useLoansByAccounts } from '@/src/subgraph-hooks'; +// import { CollIndex } from '@/src/types'; +// import { useLoansByAccounts } from '@/src/subgraph-hooks'; import { getEnsName } from 'viem/ens'; import { getMainnetPublicClient } from '@/src/shellpoints/utils/client'; -const LOCAL_STORAGE_STABILITY_POOL_DEPOSITORS_DATA = 'yusnd_stability_pool_depositors_data'; -const LOCAL_STORAGE_STABILITY_POOL_DEPOSITORS_DATA_EXPIRY = 'yusnd_stability_pool_depositors_data_expiry'; +// const LOCAL_STORAGE_STABILITY_POOL_DEPOSITORS_DATA = 'yusnd_stability_pool_depositors_data'; +// const LOCAL_STORAGE_STABILITY_POOL_DEPOSITORS_DATA_EXPIRY = 'yusnd_stability_pool_depositors_data_expiry'; -function getExpiryTime() { - const now = new Date(); - const utcYear = now.getUTCFullYear(); - const utcMonth = now.getUTCMonth(); - const utcDate = now.getUTCDate(); - // 18:00 UTC today - const refreshTime = Date.UTC(utcYear, utcMonth, utcDate, 18, 5, 0, 0); // 5 minutes after 18:00 UTC today - if (refreshTime < now.getTime()) { - return refreshTime + 1000 * 60 * 60 * 24; - } - return refreshTime; -}; +// function getExpiryTime() { +// const now = new Date(); +// const utcYear = now.getUTCFullYear(); +// const utcMonth = now.getUTCMonth(); +// const utcDate = now.getUTCDate(); +// // 18:00 UTC today +// const refreshTime = Date.UTC(utcYear, utcMonth, utcDate, 18, 5, 0, 0); // 5 minutes after 18:00 UTC today +// if (refreshTime < now.getTime()) { +// return refreshTime + 1000 * 60 * 60 * 24; +// } +// return refreshTime; +// }; -function useStabilityPoolDepositors(addresses?: Address[]) { - return useQuery({ - queryKey: ['stability-pool-depositors', addresses], - queryFn: async () => { - if (typeof localStorage !== 'undefined') { - const stabilityPoolDepositorsLS = localStorage.getItem(LOCAL_STORAGE_STABILITY_POOL_DEPOSITORS_DATA); - const stabilityPoolDepositorsExpiry = localStorage.getItem(LOCAL_STORAGE_STABILITY_POOL_DEPOSITORS_DATA_EXPIRY); - if (stabilityPoolDepositorsLS && stabilityPoolDepositorsExpiry && Number(stabilityPoolDepositorsExpiry) >= Date.now()) { - return JSON.parse(stabilityPoolDepositorsLS) as { stabilityPool: Record<`0x${string}`, { branch: CollIndex, amount: string, blockNumber: string, decimals: number }[]>, yusnd: Address[] }; - } - } - const response = await fetch('/api/stability-pool', { - method: 'POST', - body: JSON.stringify({ addresses }), - }); - const data = await response.json() as { - success: boolean; - result: { - stabilityPool: Record<`0x${string}`, { - branch: CollIndex; - amount: string; - blockNumber: string; - decimals: number; - }[]>, - yusnd: Address[] - } | undefined; - error: string | undefined; - }; - if (!data.success) { - throw new Error(data.error); - } - if (typeof localStorage !== 'undefined') { - localStorage.setItem(LOCAL_STORAGE_STABILITY_POOL_DEPOSITORS_DATA, JSON.stringify(data.result)); - localStorage.setItem(LOCAL_STORAGE_STABILITY_POOL_DEPOSITORS_DATA_EXPIRY, getExpiryTime().toString()); - } - return data.result; - }, - enabled: addresses && addresses.length > 0, - }) -} +// function useStabilityPoolDepositors(addresses?: Address[]) { +// return useQuery({ +// queryKey: ['stability-pool-depositors', addresses], +// queryFn: async () => { +// if (typeof localStorage !== 'undefined') { +// const stabilityPoolDepositorsLS = localStorage.getItem(LOCAL_STORAGE_STABILITY_POOL_DEPOSITORS_DATA); +// const stabilityPoolDepositorsExpiry = localStorage.getItem(LOCAL_STORAGE_STABILITY_POOL_DEPOSITORS_DATA_EXPIRY); +// if (stabilityPoolDepositorsLS && stabilityPoolDepositorsExpiry && Number(stabilityPoolDepositorsExpiry) >= Date.now()) { +// return JSON.parse(stabilityPoolDepositorsLS) as { stabilityPool: Record<`0x${string}`, { branch: CollIndex, amount: string, blockNumber: string, decimals: number }[]>, yusnd: Address[] }; +// } +// } +// const response = await fetch('/api/stability-pool', { +// method: 'POST', +// body: JSON.stringify({ addresses }), +// }); +// const data = await response.json() as { +// success: boolean; +// result: { +// stabilityPool: Record<`0x${string}`, { +// branch: CollIndex; +// amount: string; +// blockNumber: string; +// decimals: number; +// }[]>, +// yusnd: Address[] +// } | undefined; +// error: string | undefined; +// }; +// if (!data.success) { +// throw new Error(data.error); +// } +// if (typeof localStorage !== 'undefined') { +// localStorage.setItem(LOCAL_STORAGE_STABILITY_POOL_DEPOSITORS_DATA, JSON.stringify(data.result)); +// localStorage.setItem(LOCAL_STORAGE_STABILITY_POOL_DEPOSITORS_DATA_EXPIRY, getExpiryTime().toString()); +// } +// return data.result; +// }, +// enabled: addresses && addresses.length > 0, +// }) +// } function useEnsNames(addresses?: Address[]) { return useQuery({ @@ -82,45 +82,45 @@ function useEnsNames(addresses?: Address[]) { }) } -type LeaderboardActivityLabel = - | "yUSND" - | "Balancer" - | "Bunni" - | "Camelot" - | "Spectra" - | "Uniswap" - | "GoSlow NFT" - | "Borrowing" - | "Stability Pool"; +// type LeaderboardActivityLabel = +// | "yUSND" +// | "Balancer" +// | "Bunni" +// | "Camelot" +// | "Spectra" +// | "Uniswap" +// | "GoSlow NFT" +// | "Borrowing" +// | "Stability Pool"; -function getLeaderboardActivityName(activity: Address): LeaderboardActivityLabel | null { - switch (activity.toLowerCase()) { - case CONTRACT_ADDRESSES.YUSND.toLowerCase(): - return "yUSND"; - case CONTRACT_ADDRESSES.strategies.Balancer.toLowerCase(): - return "Balancer"; - case CONTRACT_ADDRESSES.strategies.Balancer2.toLowerCase(): - return "Balancer"; - case CONTRACT_ADDRESSES.strategies.Balancer3.toLowerCase(): - return "Balancer"; - case CONTRACT_ADDRESSES.strategies.Bunni.toLowerCase(): - return "Bunni"; - case CONTRACT_ADDRESSES.strategies.Camelot.toLowerCase(): - return "Camelot"; - case CONTRACT_ADDRESSES.strategies.Spectra.toLowerCase(): - return "Spectra"; - case CONTRACT_ADDRESSES.GoSlowNft.toLowerCase(): - return "GoSlow NFT"; - case CONTRACT_ADDRESSES.strategies.UniswapV4.toLowerCase(): - return "Uniswap"; - // case "trove": - // return "Borrowing"; - // case "stabilityPool": - // return "Stability Pool"; - default: - return null; - } -} +// function getLeaderboardActivityName(activity: Address): LeaderboardActivityLabel | null { +// switch (activity.toLowerCase()) { +// case CONTRACT_ADDRESSES.YUSND.toLowerCase(): +// return "yUSND"; +// case CONTRACT_ADDRESSES.strategies.Balancer.toLowerCase(): +// return "Balancer"; +// case CONTRACT_ADDRESSES.strategies.Balancer2.toLowerCase(): +// return "Balancer"; +// case CONTRACT_ADDRESSES.strategies.Balancer3.toLowerCase(): +// return "Balancer"; +// case CONTRACT_ADDRESSES.strategies.Bunni.toLowerCase(): +// return "Bunni"; +// case CONTRACT_ADDRESSES.strategies.Camelot.toLowerCase(): +// return "Camelot"; +// case CONTRACT_ADDRESSES.strategies.Spectra.toLowerCase(): +// return "Spectra"; +// case CONTRACT_ADDRESSES.GoSlowNft.toLowerCase(): +// return "GoSlow NFT"; +// case CONTRACT_ADDRESSES.strategies.UniswapV4.toLowerCase(): +// return "Uniswap"; +// // case "trove": +// // return "Borrowing"; +// // case "stabilityPool": +// // return "Stability Pool"; +// default: +// return null; +// } +// } export default function ShellsPage() { const [searchQuery, setSearchQuery] = useState(''); @@ -133,34 +133,40 @@ export default function ShellsPage() { } = useShellBalances(); const shellHolders = shellBalances?.map((balance) => getAddress(balance.holder)); const { - data: shellActivitiesOfHolders, - isLoading: isLoadingShellActivitiesOfHolders, - error: errorShellActivitiesOfHolders - } = useShellActivitiesOfHolders(shellHolders); - const { - data: stabilityPoolDepositors, - isLoading: isLoadingStabilityPoolDepositors, - error: errorStabilityPoolDepositors - } = useStabilityPoolDepositors(shellHolders); - const { - data: loansByAccounts, - isLoading: isLoadingLoansByAccounts, - error: errorLoansByAccounts - } = useLoansByAccounts(shellHolders); + data: shellAllocations, + isLoading: isLoadingShellAllocations, + error: errorShellAllocations + } = useAllocations(shellHolders); + // const { + // data: shellActivitiesOfHolders, + // isLoading: isLoadingShellActivitiesOfHolders, + // error: errorShellActivitiesOfHolders + // } = useShellActivitiesOfHolders(shellHolders); + // const { + // data: stabilityPoolDepositors, + // isLoading: isLoadingStabilityPoolDepositors, + // error: errorStabilityPoolDepositors + // } = useStabilityPoolDepositors(shellHolders); + // const { + // data: loansByAccounts, + // isLoading: isLoadingLoansByAccounts, + // error: errorLoansByAccounts + // } = useLoansByAccounts(shellHolders); const { data: ensNames } = useEnsNames(shellHolders); const users = useMemo(() => { return shellBalances?.map((balance, index) => { const address = getAddress(balance.holder); - const activities = Array.from(new Set([ - ...(loansByAccounts && loansByAccounts.some(loan => isAddressEqual(getAddress(loan.borrower), address)) ? ['Borrowing'] : []), - ...(stabilityPoolDepositors && Object.keys(stabilityPoolDepositors.stabilityPool).some(depositor => isAddressEqual(getAddress(depositor), address)) ? ['Stability Pool'] : []), - ...(stabilityPoolDepositors && stabilityPoolDepositors.yusnd.some(depositor => isAddressEqual(getAddress(depositor), address)) ? ['yUSND'] : []), - ...(shellActivitiesOfHolders?.filter( - (activity) => isAddressEqual(getAddress(activity.holder), address) - ) - .map((activity) => getLeaderboardActivityName(getAddress(activity.token))) ?? []).filter((activity) => activity !== null), - ] as LeaderboardActivityLabel[])); + // const activities = Array.from(new Set([ + // ...(loansByAccounts && loansByAccounts.some(loan => isAddressEqual(getAddress(loan.borrower), address)) ? ['Borrowing'] : []), + // ...(stabilityPoolDepositors && Object.keys(stabilityPoolDepositors.stabilityPool).some(depositor => isAddressEqual(getAddress(depositor), address)) ? ['Stability Pool'] : []), + // ...(stabilityPoolDepositors && stabilityPoolDepositors.yusnd.some(depositor => isAddressEqual(getAddress(depositor), address)) ? ['yUSND'] : []), + // ...(shellActivitiesOfHolders?.filter( + // (activity) => isAddressEqual(getAddress(activity.holder), address) + // ) + // .map((activity) => getLeaderboardActivityName(getAddress(activity.token))) ?? []).filter((activity) => activity !== null), + // ] as LeaderboardActivityLabel[])); + const activities = shellAllocations?.find(allocation => isAddressEqual(getAddress(allocation.user), address))?.activities.map(activity => activity.label) ?? []; return { address, ensName: ensNames?.find(ensName => isAddressEqual(ensName.address, address))?.ensName ?? null, @@ -168,11 +174,12 @@ export default function ShellsPage() { total: parseInt(formatUnits(balance.balance, 18)), mostRecent: null, }, - activities: activities.length > 0 ? activities : ['Stability Pool'], + activities, + // activities: activities.length > 0 ? activities : ['Stability Pool'], rank: index + 1, } }) ?? []; - }, [shellBalances, shellActivitiesOfHolders, stabilityPoolDepositors, loansByAccounts, ensNames]); + }, [shellBalances, shellAllocations, ensNames]); const filteredUsers = useMemo(() => { return users?.filter(user => @@ -188,8 +195,8 @@ export default function ShellsPage() { // console.log("loansByAccounts", loansByAccounts); // }, [shellBalances, shellActivitiesOfHolders, stabilityPoolDepositors, loansByAccounts]); - const isLoading = isLoadingShellBalances || isLoadingShellActivitiesOfHolders || isLoadingStabilityPoolDepositors || isLoadingLoansByAccounts; - const error = errorShellBalances || errorShellActivitiesOfHolders || errorStabilityPoolDepositors || errorLoansByAccounts; + const isLoading = isLoadingShellBalances || isLoadingShellAllocations; + const error = errorShellBalances || errorShellAllocations; const formatAddress = (address: string) => { return `${address.slice(0, 6)}...${address.slice(-4)}`; diff --git a/frontend/app/src/env.ts b/frontend/app/src/env.ts index f1a2aea31..190621864 100644 --- a/frontend/app/src/env.ts +++ b/frontend/app/src/env.ts @@ -132,7 +132,6 @@ export const EnvSchema = v.pipe( SAFE_API_URL: v.optional(v.pipe(v.string(), v.url())), SQUID_INTEGRATOR_ID: v.optional(v.string(), ""), SUBGRAPH_URL: v.pipe(v.string(), v.url()), - SUBGRAPH_URL_SERVER: v.pipe(v.string(), v.url()), SHELL_SUBGRAPH_URL: v.pipe(v.string(), v.url()), UNISWAP_V4_SUBGRAPH_URL: v.pipe(v.string(), v.url()), VERCEL_ANALYTICS: v.optional(vEnvFlag(), "false"), @@ -391,7 +390,6 @@ const parsedEnv = v.safeParse(EnvSchema, { LIQUITY_STATS_URL: process.env.NEXT_PUBLIC_LIQUITY_STATS_URL, SAFE_API_URL: process.env.NEXT_PUBLIC_SAFE_API_URL, SUBGRAPH_URL: process.env.NEXT_PUBLIC_SUBGRAPH_URL, - SUBGRAPH_URL_SERVER: process.env.NEXT_PUBLIC_SUBGRAPH_URL_SERVER, SHELL_SUBGRAPH_URL: process.env.NEXT_PUBLIC_SHELL_SUBGRAPH_URL, UNISWAP_V4_SUBGRAPH_URL: process.env.NEXT_PUBLIC_UNISWAP_V4_SUBGRAPH_URL, VERCEL_ANALYTICS: process.env.NEXT_PUBLIC_VERCEL_ANALYTICS, @@ -590,7 +588,6 @@ export const { LIQUITY_STATS_URL, SAFE_API_URL, SUBGRAPH_URL, - SUBGRAPH_URL_SERVER, SHELL_SUBGRAPH_URL, UNISWAP_V4_SUBGRAPH_URL, VERCEL_ANALYTICS, diff --git a/frontend/app/src/shell-graphql/gql.ts b/frontend/app/src/shell-graphql/gql.ts index 29b022130..86dd3195d 100644 --- a/frontend/app/src/shell-graphql/gql.ts +++ b/frontend/app/src/shell-graphql/gql.ts @@ -17,10 +17,12 @@ import * as types from './graphql'; type Documents = { "\n query BalancesByToken($token: Bytes!) {\n balances(\n where: { token: $token }\n orderBy: balance\n orderDirection: desc\n ) {\n holder\n token\n balance\n }\n }\n": typeof types.BalancesByTokenDocument, "\n query BalancesForHolders($token: Bytes!, $holders: [Bytes!]!) {\n balances(\n where: {\n token_not: $token\n holder_in: $holders\n }\n ) {\n holder\n token\n balance\n }\n }\n": typeof types.BalancesForHoldersDocument, + "\n query Allocations($users: [Bytes!]!) {\n allocations(\n where: { user_in: $users }\n ) {\n user\n activities { label }\n }\n }\n": typeof types.AllocationsDocument }; const documents: Documents = { "\n query BalancesByToken($token: Bytes!) {\n balances(\n where: { token: $token }\n orderBy: balance\n orderDirection: desc\n ) {\n holder\n token\n balance\n }\n }\n": types.BalancesByTokenDocument, "\n query BalancesForHolders($token: Bytes!, $holders: [Bytes!]!) {\n balances(\n where: {\n token_not: $token\n holder_in: $holders\n }\n ) {\n holder\n token\n balance\n }\n }\n": types.BalancesForHoldersDocument, + "\n query Allocations($users: [Bytes!]!) {\n allocations(\n where: { user_in: $users }\n ) {\n user\n activities { label }\n }\n }\n": types.AllocationsDocument, }; /** @@ -31,6 +33,10 @@ export function graphql(source: "\n query BalancesByToken($token: Bytes!) {\n * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ export function graphql(source: "\n query BalancesForHolders($token: Bytes!, $holders: [Bytes!]!) {\n balances(\n where: {\n token_not: $token\n holder_in: $holders\n }\n ) {\n holder\n token\n balance\n }\n }\n"): typeof import('./graphql').BalancesForHoldersDocument; +/** + * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. + */ +export function graphql(source: "\n query Allocations($users: [Bytes!]!) {\n allocations(\n where: { user_in: $users }\n ) {\n user\n activities { label }\n }\n }\n"): typeof import('./graphql').AllocationsDocument; export function graphql(source: string) { diff --git a/frontend/app/src/shell-graphql/graphql.ts b/frontend/app/src/shell-graphql/graphql.ts index 69660186b..a60481bca 100644 --- a/frontend/app/src/shell-graphql/graphql.ts +++ b/frontend/app/src/shell-graphql/graphql.ts @@ -29,6 +29,54 @@ export type Scalars = { Timestamp: { input: string; output: string; } }; +export type Activity = { + __typename?: 'Activity'; + id: Scalars['Bytes']['output']; + label: Scalars['String']['output']; +}; + +export type Activity_Filter = { + /** Filter for the block changed event. */ + _change_block?: InputMaybe; + and?: InputMaybe>>; + id?: InputMaybe; + id_contains?: InputMaybe; + id_gt?: InputMaybe; + id_gte?: InputMaybe; + id_in?: InputMaybe>; + id_lt?: InputMaybe; + id_lte?: InputMaybe; + id_not?: InputMaybe; + id_not_contains?: InputMaybe; + id_not_in?: InputMaybe>; + label?: InputMaybe; + label_contains?: InputMaybe; + label_contains_nocase?: InputMaybe; + label_ends_with?: InputMaybe; + label_ends_with_nocase?: InputMaybe; + label_gt?: InputMaybe; + label_gte?: InputMaybe; + label_in?: InputMaybe>; + label_lt?: InputMaybe; + label_lte?: InputMaybe; + label_not?: InputMaybe; + label_not_contains?: InputMaybe; + label_not_contains_nocase?: InputMaybe; + label_not_ends_with?: InputMaybe; + label_not_ends_with_nocase?: InputMaybe; + label_not_in?: InputMaybe>; + label_not_starts_with?: InputMaybe; + label_not_starts_with_nocase?: InputMaybe; + label_starts_with?: InputMaybe; + label_starts_with_nocase?: InputMaybe; + or?: InputMaybe>>; +}; + +export enum Activity_OrderBy { + Id = 'id', + Label = 'label' +} + export type AddLiquidity = { __typename?: 'AddLiquidity'; blockNumber: Scalars['BigInt']['output']; @@ -140,6 +188,62 @@ export enum Aggregation_Interval { Hour = 'hour' } +export type Allocation = { + __typename?: 'Allocation'; + activities: Array; + id: Scalars['Bytes']['output']; + user: Scalars['Bytes']['output']; +}; + + +export type AllocationActivitiesArgs = { + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + skip?: InputMaybe; + where?: InputMaybe; +}; + +export type Allocation_Filter = { + /** Filter for the block changed event. */ + _change_block?: InputMaybe; + activities?: InputMaybe>; + activities_?: InputMaybe; + activities_contains?: InputMaybe>; + activities_contains_nocase?: InputMaybe>; + activities_not?: InputMaybe>; + activities_not_contains?: InputMaybe>; + activities_not_contains_nocase?: InputMaybe>; + and?: InputMaybe>>; + id?: InputMaybe; + id_contains?: InputMaybe; + id_gt?: InputMaybe; + id_gte?: InputMaybe; + id_in?: InputMaybe>; + id_lt?: InputMaybe; + id_lte?: InputMaybe; + id_not?: InputMaybe; + id_not_contains?: InputMaybe; + id_not_in?: InputMaybe>; + or?: InputMaybe>>; + user?: InputMaybe; + user_contains?: InputMaybe; + user_gt?: InputMaybe; + user_gte?: InputMaybe; + user_in?: InputMaybe>; + user_lt?: InputMaybe; + user_lte?: InputMaybe; + user_not?: InputMaybe; + user_not_contains?: InputMaybe; + user_not_in?: InputMaybe>; +}; + +export enum Allocation_OrderBy { + Activities = 'activities', + Id = 'id', + User = 'user' +} + export type AmpUpdateStarted = { __typename?: 'AmpUpdateStarted'; blockNumber: Scalars['BigInt']['output']; @@ -634,6 +738,56 @@ export type Block_Height = { number_gte?: InputMaybe; }; +export type BorrowerInfo = { + __typename?: 'BorrowerInfo'; + id: Scalars['ID']['output']; + nextOwnerIndexes: Array; + troves: Scalars['Int']['output']; + trovesByCollateral: Array; +}; + +export type BorrowerInfo_Filter = { + /** Filter for the block changed event. */ + _change_block?: InputMaybe; + and?: InputMaybe>>; + id?: InputMaybe; + id_gt?: InputMaybe; + id_gte?: InputMaybe; + id_in?: InputMaybe>; + id_lt?: InputMaybe; + id_lte?: InputMaybe; + id_not?: InputMaybe; + id_not_in?: InputMaybe>; + nextOwnerIndexes?: InputMaybe>; + nextOwnerIndexes_contains?: InputMaybe>; + nextOwnerIndexes_contains_nocase?: InputMaybe>; + nextOwnerIndexes_not?: InputMaybe>; + nextOwnerIndexes_not_contains?: InputMaybe>; + nextOwnerIndexes_not_contains_nocase?: InputMaybe>; + or?: InputMaybe>>; + troves?: InputMaybe; + trovesByCollateral?: InputMaybe>; + trovesByCollateral_contains?: InputMaybe>; + trovesByCollateral_contains_nocase?: InputMaybe>; + trovesByCollateral_not?: InputMaybe>; + trovesByCollateral_not_contains?: InputMaybe>; + trovesByCollateral_not_contains_nocase?: InputMaybe>; + troves_gt?: InputMaybe; + troves_gte?: InputMaybe; + troves_in?: InputMaybe>; + troves_lt?: InputMaybe; + troves_lte?: InputMaybe; + troves_not?: InputMaybe; + troves_not_in?: InputMaybe>; +}; + +export enum BorrowerInfo_OrderBy { + Id = 'id', + NextOwnerIndexes = 'nextOwnerIndexes', + Troves = 'troves', + TrovesByCollateral = 'trovesByCollateral' +} + export type BunniTokenApproval = { __typename?: 'BunniTokenApproval'; blockNumber: Scalars['BigInt']['output']; @@ -1186,6 +1340,290 @@ export enum CamelotPairTransfer_OrderBy { Value = 'value' } +export type CollSurplus = { + __typename?: 'CollSurplus'; + amount: Scalars['BigInt']['output']; + id: Scalars['String']['output']; +}; + +export type CollSurplus_Filter = { + /** Filter for the block changed event. */ + _change_block?: InputMaybe; + amount?: InputMaybe; + amount_gt?: InputMaybe; + amount_gte?: InputMaybe; + amount_in?: InputMaybe>; + amount_lt?: InputMaybe; + amount_lte?: InputMaybe; + amount_not?: InputMaybe; + amount_not_in?: InputMaybe>; + and?: InputMaybe>>; + id?: InputMaybe; + id_contains?: InputMaybe; + id_contains_nocase?: InputMaybe; + id_ends_with?: InputMaybe; + id_ends_with_nocase?: InputMaybe; + id_gt?: InputMaybe; + id_gte?: InputMaybe; + id_in?: InputMaybe>; + id_lt?: InputMaybe; + id_lte?: InputMaybe; + id_not?: InputMaybe; + id_not_contains?: InputMaybe; + id_not_contains_nocase?: InputMaybe; + id_not_ends_with?: InputMaybe; + id_not_ends_with_nocase?: InputMaybe; + id_not_in?: InputMaybe>; + id_not_starts_with?: InputMaybe; + id_not_starts_with_nocase?: InputMaybe; + id_starts_with?: InputMaybe; + id_starts_with_nocase?: InputMaybe; + or?: InputMaybe>>; +}; + +export enum CollSurplus_OrderBy { + Amount = 'amount', + Id = 'id' +} + +export type Collateral = { + __typename?: 'Collateral'; + addresses: CollateralAddresses; + collIndex: Scalars['Int']['output']; + debtLimit: Scalars['BigInt']['output']; + id: Scalars['ID']['output']; + minCollRatio: Scalars['BigInt']['output']; + stabilityPoolDeposits: Array; + token: Token; + troves: Array; +}; + + +export type CollateralStabilityPoolDepositsArgs = { + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + skip?: InputMaybe; + where?: InputMaybe; +}; + + +export type CollateralTrovesArgs = { + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + skip?: InputMaybe; + where?: InputMaybe; +}; + +export type CollateralAddresses = { + __typename?: 'CollateralAddresses'; + borrowerOperations: Scalars['Bytes']['output']; + collateral: Collateral; + id: Scalars['ID']['output']; + sortedTroves: Scalars['Bytes']['output']; + stabilityPool: Scalars['Bytes']['output']; + token: Scalars['Bytes']['output']; + troveManager: Scalars['Bytes']['output']; + troveNft: Scalars['Bytes']['output']; +}; + +export type CollateralAddresses_Filter = { + /** Filter for the block changed event. */ + _change_block?: InputMaybe; + and?: InputMaybe>>; + borrowerOperations?: InputMaybe; + borrowerOperations_contains?: InputMaybe; + borrowerOperations_gt?: InputMaybe; + borrowerOperations_gte?: InputMaybe; + borrowerOperations_in?: InputMaybe>; + borrowerOperations_lt?: InputMaybe; + borrowerOperations_lte?: InputMaybe; + borrowerOperations_not?: InputMaybe; + borrowerOperations_not_contains?: InputMaybe; + borrowerOperations_not_in?: InputMaybe>; + collateral?: InputMaybe; + collateral_?: InputMaybe; + collateral_contains?: InputMaybe; + collateral_contains_nocase?: InputMaybe; + collateral_ends_with?: InputMaybe; + collateral_ends_with_nocase?: InputMaybe; + collateral_gt?: InputMaybe; + collateral_gte?: InputMaybe; + collateral_in?: InputMaybe>; + collateral_lt?: InputMaybe; + collateral_lte?: InputMaybe; + collateral_not?: InputMaybe; + collateral_not_contains?: InputMaybe; + collateral_not_contains_nocase?: InputMaybe; + collateral_not_ends_with?: InputMaybe; + collateral_not_ends_with_nocase?: InputMaybe; + collateral_not_in?: InputMaybe>; + collateral_not_starts_with?: InputMaybe; + collateral_not_starts_with_nocase?: InputMaybe; + collateral_starts_with?: InputMaybe; + collateral_starts_with_nocase?: InputMaybe; + id?: InputMaybe; + id_gt?: InputMaybe; + id_gte?: InputMaybe; + id_in?: InputMaybe>; + id_lt?: InputMaybe; + id_lte?: InputMaybe; + id_not?: InputMaybe; + id_not_in?: InputMaybe>; + or?: InputMaybe>>; + sortedTroves?: InputMaybe; + sortedTroves_contains?: InputMaybe; + sortedTroves_gt?: InputMaybe; + sortedTroves_gte?: InputMaybe; + sortedTroves_in?: InputMaybe>; + sortedTroves_lt?: InputMaybe; + sortedTroves_lte?: InputMaybe; + sortedTroves_not?: InputMaybe; + sortedTroves_not_contains?: InputMaybe; + sortedTroves_not_in?: InputMaybe>; + stabilityPool?: InputMaybe; + stabilityPool_contains?: InputMaybe; + stabilityPool_gt?: InputMaybe; + stabilityPool_gte?: InputMaybe; + stabilityPool_in?: InputMaybe>; + stabilityPool_lt?: InputMaybe; + stabilityPool_lte?: InputMaybe; + stabilityPool_not?: InputMaybe; + stabilityPool_not_contains?: InputMaybe; + stabilityPool_not_in?: InputMaybe>; + token?: InputMaybe; + token_contains?: InputMaybe; + token_gt?: InputMaybe; + token_gte?: InputMaybe; + token_in?: InputMaybe>; + token_lt?: InputMaybe; + token_lte?: InputMaybe; + token_not?: InputMaybe; + token_not_contains?: InputMaybe; + token_not_in?: InputMaybe>; + troveManager?: InputMaybe; + troveManager_contains?: InputMaybe; + troveManager_gt?: InputMaybe; + troveManager_gte?: InputMaybe; + troveManager_in?: InputMaybe>; + troveManager_lt?: InputMaybe; + troveManager_lte?: InputMaybe; + troveManager_not?: InputMaybe; + troveManager_not_contains?: InputMaybe; + troveManager_not_in?: InputMaybe>; + troveNft?: InputMaybe; + troveNft_contains?: InputMaybe; + troveNft_gt?: InputMaybe; + troveNft_gte?: InputMaybe; + troveNft_in?: InputMaybe>; + troveNft_lt?: InputMaybe; + troveNft_lte?: InputMaybe; + troveNft_not?: InputMaybe; + troveNft_not_contains?: InputMaybe; + troveNft_not_in?: InputMaybe>; +}; + +export enum CollateralAddresses_OrderBy { + BorrowerOperations = 'borrowerOperations', + Collateral = 'collateral', + CollateralCollIndex = 'collateral__collIndex', + CollateralDebtLimit = 'collateral__debtLimit', + CollateralId = 'collateral__id', + CollateralMinCollRatio = 'collateral__minCollRatio', + Id = 'id', + SortedTroves = 'sortedTroves', + StabilityPool = 'stabilityPool', + Token = 'token', + TroveManager = 'troveManager', + TroveNft = 'troveNft' +} + +export type Collateral_Filter = { + /** Filter for the block changed event. */ + _change_block?: InputMaybe; + addresses_?: InputMaybe; + and?: InputMaybe>>; + collIndex?: InputMaybe; + collIndex_gt?: InputMaybe; + collIndex_gte?: InputMaybe; + collIndex_in?: InputMaybe>; + collIndex_lt?: InputMaybe; + collIndex_lte?: InputMaybe; + collIndex_not?: InputMaybe; + collIndex_not_in?: InputMaybe>; + debtLimit?: InputMaybe; + debtLimit_gt?: InputMaybe; + debtLimit_gte?: InputMaybe; + debtLimit_in?: InputMaybe>; + debtLimit_lt?: InputMaybe; + debtLimit_lte?: InputMaybe; + debtLimit_not?: InputMaybe; + debtLimit_not_in?: InputMaybe>; + id?: InputMaybe; + id_gt?: InputMaybe; + id_gte?: InputMaybe; + id_in?: InputMaybe>; + id_lt?: InputMaybe; + id_lte?: InputMaybe; + id_not?: InputMaybe; + id_not_in?: InputMaybe>; + minCollRatio?: InputMaybe; + minCollRatio_gt?: InputMaybe; + minCollRatio_gte?: InputMaybe; + minCollRatio_in?: InputMaybe>; + minCollRatio_lt?: InputMaybe; + minCollRatio_lte?: InputMaybe; + minCollRatio_not?: InputMaybe; + minCollRatio_not_in?: InputMaybe>; + or?: InputMaybe>>; + stabilityPoolDeposits_?: InputMaybe; + token?: InputMaybe; + token_?: InputMaybe; + token_contains?: InputMaybe; + token_contains_nocase?: InputMaybe; + token_ends_with?: InputMaybe; + token_ends_with_nocase?: InputMaybe; + token_gt?: InputMaybe; + token_gte?: InputMaybe; + token_in?: InputMaybe>; + token_lt?: InputMaybe; + token_lte?: InputMaybe; + token_not?: InputMaybe; + token_not_contains?: InputMaybe; + token_not_contains_nocase?: InputMaybe; + token_not_ends_with?: InputMaybe; + token_not_ends_with_nocase?: InputMaybe; + token_not_in?: InputMaybe>; + token_not_starts_with?: InputMaybe; + token_not_starts_with_nocase?: InputMaybe; + token_starts_with?: InputMaybe; + token_starts_with_nocase?: InputMaybe; + troves_?: InputMaybe; +}; + +export enum Collateral_OrderBy { + Addresses = 'addresses', + AddressesBorrowerOperations = 'addresses__borrowerOperations', + AddressesId = 'addresses__id', + AddressesSortedTroves = 'addresses__sortedTroves', + AddressesStabilityPool = 'addresses__stabilityPool', + AddressesToken = 'addresses__token', + AddressesTroveManager = 'addresses__troveManager', + AddressesTroveNft = 'addresses__troveNft', + CollIndex = 'collIndex', + DebtLimit = 'debtLimit', + Id = 'id', + MinCollRatio = 'minCollRatio', + StabilityPoolDeposits = 'stabilityPoolDeposits', + Token = 'token', + TokenDecimals = 'token__decimals', + TokenId = 'token__id', + TokenName = 'token__name', + TokenSymbol = 'token__symbol', + Troves = 'troves' +} + export type CurveStableSwapNgApproval = { __typename?: 'CurveStableSwapNGApproval'; blockNumber: Scalars['BigInt']['output']; @@ -1588,6 +2026,192 @@ export enum FeePercentUpdated_OrderBy { TransactionHash = 'transactionHash' } +export type InterestBatch = { + __typename?: 'InterestBatch'; + annualInterestRate: Scalars['BigInt']['output']; + annualManagementFee: Scalars['BigInt']['output']; + batchManager: Scalars['Bytes']['output']; + coll: Scalars['BigInt']['output']; + collateral: Collateral; + debt: Scalars['BigInt']['output']; + id: Scalars['ID']['output']; + troves: Array; +}; + + +export type InterestBatchTrovesArgs = { + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + skip?: InputMaybe; + where?: InputMaybe; +}; + +export type InterestBatch_Filter = { + /** Filter for the block changed event. */ + _change_block?: InputMaybe; + and?: InputMaybe>>; + annualInterestRate?: InputMaybe; + annualInterestRate_gt?: InputMaybe; + annualInterestRate_gte?: InputMaybe; + annualInterestRate_in?: InputMaybe>; + annualInterestRate_lt?: InputMaybe; + annualInterestRate_lte?: InputMaybe; + annualInterestRate_not?: InputMaybe; + annualInterestRate_not_in?: InputMaybe>; + annualManagementFee?: InputMaybe; + annualManagementFee_gt?: InputMaybe; + annualManagementFee_gte?: InputMaybe; + annualManagementFee_in?: InputMaybe>; + annualManagementFee_lt?: InputMaybe; + annualManagementFee_lte?: InputMaybe; + annualManagementFee_not?: InputMaybe; + annualManagementFee_not_in?: InputMaybe>; + batchManager?: InputMaybe; + batchManager_contains?: InputMaybe; + batchManager_gt?: InputMaybe; + batchManager_gte?: InputMaybe; + batchManager_in?: InputMaybe>; + batchManager_lt?: InputMaybe; + batchManager_lte?: InputMaybe; + batchManager_not?: InputMaybe; + batchManager_not_contains?: InputMaybe; + batchManager_not_in?: InputMaybe>; + coll?: InputMaybe; + coll_gt?: InputMaybe; + coll_gte?: InputMaybe; + coll_in?: InputMaybe>; + coll_lt?: InputMaybe; + coll_lte?: InputMaybe; + coll_not?: InputMaybe; + coll_not_in?: InputMaybe>; + collateral?: InputMaybe; + collateral_?: InputMaybe; + collateral_contains?: InputMaybe; + collateral_contains_nocase?: InputMaybe; + collateral_ends_with?: InputMaybe; + collateral_ends_with_nocase?: InputMaybe; + collateral_gt?: InputMaybe; + collateral_gte?: InputMaybe; + collateral_in?: InputMaybe>; + collateral_lt?: InputMaybe; + collateral_lte?: InputMaybe; + collateral_not?: InputMaybe; + collateral_not_contains?: InputMaybe; + collateral_not_contains_nocase?: InputMaybe; + collateral_not_ends_with?: InputMaybe; + collateral_not_ends_with_nocase?: InputMaybe; + collateral_not_in?: InputMaybe>; + collateral_not_starts_with?: InputMaybe; + collateral_not_starts_with_nocase?: InputMaybe; + collateral_starts_with?: InputMaybe; + collateral_starts_with_nocase?: InputMaybe; + debt?: InputMaybe; + debt_gt?: InputMaybe; + debt_gte?: InputMaybe; + debt_in?: InputMaybe>; + debt_lt?: InputMaybe; + debt_lte?: InputMaybe; + debt_not?: InputMaybe; + debt_not_in?: InputMaybe>; + id?: InputMaybe; + id_gt?: InputMaybe; + id_gte?: InputMaybe; + id_in?: InputMaybe>; + id_lt?: InputMaybe; + id_lte?: InputMaybe; + id_not?: InputMaybe; + id_not_in?: InputMaybe>; + or?: InputMaybe>>; + troves_?: InputMaybe; +}; + +export enum InterestBatch_OrderBy { + AnnualInterestRate = 'annualInterestRate', + AnnualManagementFee = 'annualManagementFee', + BatchManager = 'batchManager', + Coll = 'coll', + Collateral = 'collateral', + CollateralCollIndex = 'collateral__collIndex', + CollateralDebtLimit = 'collateral__debtLimit', + CollateralId = 'collateral__id', + CollateralMinCollRatio = 'collateral__minCollRatio', + Debt = 'debt', + Id = 'id', + Troves = 'troves' +} + +export type InterestRateBracket = { + __typename?: 'InterestRateBracket'; + collateral: Collateral; + id: Scalars['ID']['output']; + rate: Scalars['BigInt']['output']; + totalDebt: Scalars['BigInt']['output']; +}; + +export type InterestRateBracket_Filter = { + /** Filter for the block changed event. */ + _change_block?: InputMaybe; + and?: InputMaybe>>; + collateral?: InputMaybe; + collateral_?: InputMaybe; + collateral_contains?: InputMaybe; + collateral_contains_nocase?: InputMaybe; + collateral_ends_with?: InputMaybe; + collateral_ends_with_nocase?: InputMaybe; + collateral_gt?: InputMaybe; + collateral_gte?: InputMaybe; + collateral_in?: InputMaybe>; + collateral_lt?: InputMaybe; + collateral_lte?: InputMaybe; + collateral_not?: InputMaybe; + collateral_not_contains?: InputMaybe; + collateral_not_contains_nocase?: InputMaybe; + collateral_not_ends_with?: InputMaybe; + collateral_not_ends_with_nocase?: InputMaybe; + collateral_not_in?: InputMaybe>; + collateral_not_starts_with?: InputMaybe; + collateral_not_starts_with_nocase?: InputMaybe; + collateral_starts_with?: InputMaybe; + collateral_starts_with_nocase?: InputMaybe; + id?: InputMaybe; + id_gt?: InputMaybe; + id_gte?: InputMaybe; + id_in?: InputMaybe>; + id_lt?: InputMaybe; + id_lte?: InputMaybe; + id_not?: InputMaybe; + id_not_in?: InputMaybe>; + or?: InputMaybe>>; + rate?: InputMaybe; + rate_gt?: InputMaybe; + rate_gte?: InputMaybe; + rate_in?: InputMaybe>; + rate_lt?: InputMaybe; + rate_lte?: InputMaybe; + rate_not?: InputMaybe; + rate_not_in?: InputMaybe>; + totalDebt?: InputMaybe; + totalDebt_gt?: InputMaybe; + totalDebt_gte?: InputMaybe; + totalDebt_in?: InputMaybe>; + totalDebt_lt?: InputMaybe; + totalDebt_lte?: InputMaybe; + totalDebt_not?: InputMaybe; + totalDebt_not_in?: InputMaybe>; +}; + +export enum InterestRateBracket_OrderBy { + Collateral = 'collateral', + CollateralCollIndex = 'collateral__collIndex', + CollateralDebtLimit = 'collateral__debtLimit', + CollateralId = 'collateral__id', + CollateralMinCollRatio = 'collateral__minCollRatio', + Id = 'id', + Rate = 'rate', + TotalDebt = 'totalDebt' +} + export type Lock = { __typename?: 'Lock'; account: Scalars['Bytes']['output']; @@ -1992,8 +2616,12 @@ export type Query = { __typename?: 'Query'; /** Access to subgraph metadata */ _meta?: Maybe<_Meta_>; + activities: Array; + activity?: Maybe; addLiquidities: Array; addLiquidity?: Maybe; + allocation?: Maybe; + allocations: Array; ampUpdateStarted?: Maybe; ampUpdateStarteds: Array; ampUpdateStopped?: Maybe; @@ -2006,6 +2634,8 @@ export type Query = { approvals: Array; balance?: Maybe; balances: Array; + borrowerInfo?: Maybe; + borrowerInfos: Array; bunniTokenApproval?: Maybe; bunniTokenApprovals: Array; bunniTokenOwnershipTransferred?: Maybe; @@ -2018,6 +2648,12 @@ export type Query = { camelotPairApprovals: Array; camelotPairTransfer?: Maybe; camelotPairTransfers: Array; + collSurplus?: Maybe; + collSurpluses: Array; + collateral?: Maybe; + collateralAddresses?: Maybe; + collateralAddresses_collection: Array; + collaterals: Array; curveStableSwapNGApproval?: Maybe; curveStableSwapNGApprovals: Array; curveStableSwapNGTransfer?: Maybe; @@ -2028,6 +2664,10 @@ export type Query = { eip712DomainChangeds: Array; feePercentUpdated?: Maybe; feePercentUpdateds: Array; + interestBatch?: Maybe; + interestBatches: Array; + interestRateBracket?: Maybe; + interestRateBrackets: Array; lock?: Maybe; locks: Array; mint?: Maybe; @@ -2056,6 +2696,12 @@ export type Query = { setStableSwaps: Array; skim?: Maybe; skims: Array; + stabilityPool?: Maybe; + stabilityPoolDeposit?: Maybe; + stabilityPoolDepositorInfo?: Maybe; + stabilityPoolDepositorInfos: Array; + stabilityPoolDeposits: Array; + stabilityPools: Array; stablePoolApproval?: Maybe; stablePoolApprovals: Array; stablePoolTransfer?: Maybe; @@ -2066,16 +2712,20 @@ export type Query = { swaps: Array; sync?: Maybe; syncs: Array; + token?: Maybe; tokenExchange?: Maybe; tokenExchangeUnderlying?: Maybe; tokenExchangeUnderlyings: Array; tokenExchanges: Array; + tokens: Array; transfer?: Maybe; transferBatch?: Maybe; transferBatches: Array; transferSingle?: Maybe; transferSingles: Array; transfers: Array; + trove?: Maybe; + troves: Array; unlock?: Maybe; unlocks: Array; uri?: Maybe; @@ -2088,6 +2738,24 @@ export type Query_MetaArgs = { }; +export type QueryActivitiesArgs = { + block?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + skip?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; + where?: InputMaybe; +}; + + +export type QueryActivityArgs = { + block?: InputMaybe; + id: Scalars['ID']['input']; + subgraphError?: _SubgraphErrorPolicy_; +}; + + export type QueryAddLiquiditiesArgs = { block?: InputMaybe; first?: InputMaybe; @@ -2106,6 +2774,24 @@ export type QueryAddLiquidityArgs = { }; +export type QueryAllocationArgs = { + block?: InputMaybe; + id: Scalars['ID']['input']; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QueryAllocationsArgs = { + block?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + skip?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; + where?: InputMaybe; +}; + + export type QueryAmpUpdateStartedArgs = { block?: InputMaybe; id: Scalars['ID']['input']; @@ -2214,6 +2900,24 @@ export type QueryBalancesArgs = { }; +export type QueryBorrowerInfoArgs = { + block?: InputMaybe; + id: Scalars['ID']['input']; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QueryBorrowerInfosArgs = { + block?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + skip?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; + where?: InputMaybe; +}; + + export type QueryBunniTokenApprovalArgs = { block?: InputMaybe; id: Scalars['ID']['input']; @@ -2322,6 +3026,60 @@ export type QueryCamelotPairTransfersArgs = { }; +export type QueryCollSurplusArgs = { + block?: InputMaybe; + id: Scalars['ID']['input']; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QueryCollSurplusesArgs = { + block?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + skip?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; + where?: InputMaybe; +}; + + +export type QueryCollateralArgs = { + block?: InputMaybe; + id: Scalars['ID']['input']; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QueryCollateralAddressesArgs = { + block?: InputMaybe; + id: Scalars['ID']['input']; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QueryCollateralAddresses_CollectionArgs = { + block?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + skip?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; + where?: InputMaybe; +}; + + +export type QueryCollateralsArgs = { + block?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + skip?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; + where?: InputMaybe; +}; + + export type QueryCurveStableSwapNgApprovalArgs = { block?: InputMaybe; id: Scalars['ID']['input']; @@ -2412,6 +3170,42 @@ export type QueryFeePercentUpdatedsArgs = { }; +export type QueryInterestBatchArgs = { + block?: InputMaybe; + id: Scalars['ID']['input']; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QueryInterestBatchesArgs = { + block?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + skip?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; + where?: InputMaybe; +}; + + +export type QueryInterestRateBracketArgs = { + block?: InputMaybe; + id: Scalars['ID']['input']; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QueryInterestRateBracketsArgs = { + block?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + skip?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; + where?: InputMaybe; +}; + + export type QueryLockArgs = { block?: InputMaybe; id: Scalars['ID']['input']; @@ -2664,6 +3458,60 @@ export type QuerySkimsArgs = { }; +export type QueryStabilityPoolArgs = { + block?: InputMaybe; + id: Scalars['ID']['input']; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QueryStabilityPoolDepositArgs = { + block?: InputMaybe; + id: Scalars['ID']['input']; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QueryStabilityPoolDepositorInfoArgs = { + block?: InputMaybe; + id: Scalars['ID']['input']; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QueryStabilityPoolDepositorInfosArgs = { + block?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + skip?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; + where?: InputMaybe; +}; + + +export type QueryStabilityPoolDepositsArgs = { + block?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + skip?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; + where?: InputMaybe; +}; + + +export type QueryStabilityPoolsArgs = { + block?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + skip?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; + where?: InputMaybe; +}; + + export type QueryStablePoolApprovalArgs = { block?: InputMaybe; id: Scalars['ID']['input']; @@ -2754,6 +3602,13 @@ export type QuerySyncsArgs = { }; +export type QueryTokenArgs = { + block?: InputMaybe; + id: Scalars['ID']['input']; + subgraphError?: _SubgraphErrorPolicy_; +}; + + export type QueryTokenExchangeArgs = { block?: InputMaybe; id: Scalars['ID']['input']; @@ -2790,6 +3645,17 @@ export type QueryTokenExchangesArgs = { }; +export type QueryTokensArgs = { + block?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + skip?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; + where?: InputMaybe; +}; + + export type QueryTransferArgs = { block?: InputMaybe; id: Scalars['ID']['input']; @@ -2844,6 +3710,24 @@ export type QueryTransfersArgs = { }; +export type QueryTroveArgs = { + block?: InputMaybe; + id: Scalars['ID']['input']; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QueryTrovesArgs = { + block?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + skip?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; + where?: InputMaybe; +}; + + export type QueryUnlockArgs = { block?: InputMaybe; id: Scalars['ID']['input']; @@ -3633,6 +4517,182 @@ export enum Skim_OrderBy { TransactionHash = 'transactionHash' } +export type StabilityPool = { + __typename?: 'StabilityPool'; + collBalance: Scalars['BigInt']['output']; + id: Scalars['ID']['output']; + totalDeposited: Scalars['BigInt']['output']; +}; + +export type StabilityPoolDeposit = { + __typename?: 'StabilityPoolDeposit'; + collateral: Collateral; + deposit: Scalars['BigInt']['output']; + depositor: StabilityPoolDepositorInfo; + id: Scalars['ID']['output']; +}; + +export type StabilityPoolDeposit_Filter = { + /** Filter for the block changed event. */ + _change_block?: InputMaybe; + and?: InputMaybe>>; + collateral?: InputMaybe; + collateral_?: InputMaybe; + collateral_contains?: InputMaybe; + collateral_contains_nocase?: InputMaybe; + collateral_ends_with?: InputMaybe; + collateral_ends_with_nocase?: InputMaybe; + collateral_gt?: InputMaybe; + collateral_gte?: InputMaybe; + collateral_in?: InputMaybe>; + collateral_lt?: InputMaybe; + collateral_lte?: InputMaybe; + collateral_not?: InputMaybe; + collateral_not_contains?: InputMaybe; + collateral_not_contains_nocase?: InputMaybe; + collateral_not_ends_with?: InputMaybe; + collateral_not_ends_with_nocase?: InputMaybe; + collateral_not_in?: InputMaybe>; + collateral_not_starts_with?: InputMaybe; + collateral_not_starts_with_nocase?: InputMaybe; + collateral_starts_with?: InputMaybe; + collateral_starts_with_nocase?: InputMaybe; + deposit?: InputMaybe; + deposit_gt?: InputMaybe; + deposit_gte?: InputMaybe; + deposit_in?: InputMaybe>; + deposit_lt?: InputMaybe; + deposit_lte?: InputMaybe; + deposit_not?: InputMaybe; + deposit_not_in?: InputMaybe>; + depositor?: InputMaybe; + depositor_?: InputMaybe; + depositor_contains?: InputMaybe; + depositor_contains_nocase?: InputMaybe; + depositor_ends_with?: InputMaybe; + depositor_ends_with_nocase?: InputMaybe; + depositor_gt?: InputMaybe; + depositor_gte?: InputMaybe; + depositor_in?: InputMaybe>; + depositor_lt?: InputMaybe; + depositor_lte?: InputMaybe; + depositor_not?: InputMaybe; + depositor_not_contains?: InputMaybe; + depositor_not_contains_nocase?: InputMaybe; + depositor_not_ends_with?: InputMaybe; + depositor_not_ends_with_nocase?: InputMaybe; + depositor_not_in?: InputMaybe>; + depositor_not_starts_with?: InputMaybe; + depositor_not_starts_with_nocase?: InputMaybe; + depositor_starts_with?: InputMaybe; + depositor_starts_with_nocase?: InputMaybe; + id?: InputMaybe; + id_gt?: InputMaybe; + id_gte?: InputMaybe; + id_in?: InputMaybe>; + id_lt?: InputMaybe; + id_lte?: InputMaybe; + id_not?: InputMaybe; + id_not_in?: InputMaybe>; + or?: InputMaybe>>; +}; + +export enum StabilityPoolDeposit_OrderBy { + Collateral = 'collateral', + CollateralCollIndex = 'collateral__collIndex', + CollateralDebtLimit = 'collateral__debtLimit', + CollateralId = 'collateral__id', + CollateralMinCollRatio = 'collateral__minCollRatio', + Deposit = 'deposit', + Depositor = 'depositor', + DepositorId = 'depositor__id', + DepositorTotalDeposited = 'depositor__totalDeposited', + Id = 'id' +} + +export type StabilityPoolDepositorInfo = { + __typename?: 'StabilityPoolDepositorInfo'; + deposits: Array; + id: Scalars['ID']['output']; + totalDeposited: Scalars['BigInt']['output']; +}; + + +export type StabilityPoolDepositorInfoDepositsArgs = { + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + skip?: InputMaybe; + where?: InputMaybe; +}; + +export type StabilityPoolDepositorInfo_Filter = { + /** Filter for the block changed event. */ + _change_block?: InputMaybe; + and?: InputMaybe>>; + deposits_?: InputMaybe; + id?: InputMaybe; + id_gt?: InputMaybe; + id_gte?: InputMaybe; + id_in?: InputMaybe>; + id_lt?: InputMaybe; + id_lte?: InputMaybe; + id_not?: InputMaybe; + id_not_in?: InputMaybe>; + or?: InputMaybe>>; + totalDeposited?: InputMaybe; + totalDeposited_gt?: InputMaybe; + totalDeposited_gte?: InputMaybe; + totalDeposited_in?: InputMaybe>; + totalDeposited_lt?: InputMaybe; + totalDeposited_lte?: InputMaybe; + totalDeposited_not?: InputMaybe; + totalDeposited_not_in?: InputMaybe>; +}; + +export enum StabilityPoolDepositorInfo_OrderBy { + Deposits = 'deposits', + Id = 'id', + TotalDeposited = 'totalDeposited' +} + +export type StabilityPool_Filter = { + /** Filter for the block changed event. */ + _change_block?: InputMaybe; + and?: InputMaybe>>; + collBalance?: InputMaybe; + collBalance_gt?: InputMaybe; + collBalance_gte?: InputMaybe; + collBalance_in?: InputMaybe>; + collBalance_lt?: InputMaybe; + collBalance_lte?: InputMaybe; + collBalance_not?: InputMaybe; + collBalance_not_in?: InputMaybe>; + id?: InputMaybe; + id_gt?: InputMaybe; + id_gte?: InputMaybe; + id_in?: InputMaybe>; + id_lt?: InputMaybe; + id_lte?: InputMaybe; + id_not?: InputMaybe; + id_not_in?: InputMaybe>; + or?: InputMaybe>>; + totalDeposited?: InputMaybe; + totalDeposited_gt?: InputMaybe; + totalDeposited_gte?: InputMaybe; + totalDeposited_in?: InputMaybe>; + totalDeposited_lt?: InputMaybe; + totalDeposited_lte?: InputMaybe; + totalDeposited_not?: InputMaybe; + totalDeposited_not_in?: InputMaybe>; +}; + +export enum StabilityPool_OrderBy { + CollBalance = 'collBalance', + Id = 'id', + TotalDeposited = 'totalDeposited' +} + export type StablePoolApproval = { __typename?: 'StablePoolApproval'; blockNumber: Scalars['BigInt']['output']; @@ -4095,6 +5155,15 @@ export enum Sync_OrderBy { TransactionHash = 'transactionHash' } +export type Token = { + __typename?: 'Token'; + collateral: Collateral; + decimals: Scalars['Int']['output']; + id: Scalars['ID']['output']; + name: Scalars['String']['output']; + symbol: Scalars['String']['output']; +}; + export type TokenExchange = { __typename?: 'TokenExchange'; blockNumber: Scalars['BigInt']['output']; @@ -4315,6 +5384,102 @@ export enum TokenExchange_OrderBy { TransactionHash = 'transactionHash' } +export type Token_Filter = { + /** Filter for the block changed event. */ + _change_block?: InputMaybe; + and?: InputMaybe>>; + collateral?: InputMaybe; + collateral_?: InputMaybe; + collateral_contains?: InputMaybe; + collateral_contains_nocase?: InputMaybe; + collateral_ends_with?: InputMaybe; + collateral_ends_with_nocase?: InputMaybe; + collateral_gt?: InputMaybe; + collateral_gte?: InputMaybe; + collateral_in?: InputMaybe>; + collateral_lt?: InputMaybe; + collateral_lte?: InputMaybe; + collateral_not?: InputMaybe; + collateral_not_contains?: InputMaybe; + collateral_not_contains_nocase?: InputMaybe; + collateral_not_ends_with?: InputMaybe; + collateral_not_ends_with_nocase?: InputMaybe; + collateral_not_in?: InputMaybe>; + collateral_not_starts_with?: InputMaybe; + collateral_not_starts_with_nocase?: InputMaybe; + collateral_starts_with?: InputMaybe; + collateral_starts_with_nocase?: InputMaybe; + decimals?: InputMaybe; + decimals_gt?: InputMaybe; + decimals_gte?: InputMaybe; + decimals_in?: InputMaybe>; + decimals_lt?: InputMaybe; + decimals_lte?: InputMaybe; + decimals_not?: InputMaybe; + decimals_not_in?: InputMaybe>; + id?: InputMaybe; + id_gt?: InputMaybe; + id_gte?: InputMaybe; + id_in?: InputMaybe>; + id_lt?: InputMaybe; + id_lte?: InputMaybe; + id_not?: InputMaybe; + id_not_in?: InputMaybe>; + name?: InputMaybe; + name_contains?: InputMaybe; + name_contains_nocase?: InputMaybe; + name_ends_with?: InputMaybe; + name_ends_with_nocase?: InputMaybe; + name_gt?: InputMaybe; + name_gte?: InputMaybe; + name_in?: InputMaybe>; + name_lt?: InputMaybe; + name_lte?: InputMaybe; + name_not?: InputMaybe; + name_not_contains?: InputMaybe; + name_not_contains_nocase?: InputMaybe; + name_not_ends_with?: InputMaybe; + name_not_ends_with_nocase?: InputMaybe; + name_not_in?: InputMaybe>; + name_not_starts_with?: InputMaybe; + name_not_starts_with_nocase?: InputMaybe; + name_starts_with?: InputMaybe; + name_starts_with_nocase?: InputMaybe; + or?: InputMaybe>>; + symbol?: InputMaybe; + symbol_contains?: InputMaybe; + symbol_contains_nocase?: InputMaybe; + symbol_ends_with?: InputMaybe; + symbol_ends_with_nocase?: InputMaybe; + symbol_gt?: InputMaybe; + symbol_gte?: InputMaybe; + symbol_in?: InputMaybe>; + symbol_lt?: InputMaybe; + symbol_lte?: InputMaybe; + symbol_not?: InputMaybe; + symbol_not_contains?: InputMaybe; + symbol_not_contains_nocase?: InputMaybe; + symbol_not_ends_with?: InputMaybe; + symbol_not_ends_with_nocase?: InputMaybe; + symbol_not_in?: InputMaybe>; + symbol_not_starts_with?: InputMaybe; + symbol_not_starts_with_nocase?: InputMaybe; + symbol_starts_with?: InputMaybe; + symbol_starts_with_nocase?: InputMaybe; +}; + +export enum Token_OrderBy { + Collateral = 'collateral', + CollateralCollIndex = 'collateral__collIndex', + CollateralDebtLimit = 'collateral__debtLimit', + CollateralId = 'collateral__id', + CollateralMinCollRatio = 'collateral__minCollRatio', + Decimals = 'decimals', + Id = 'id', + Name = 'name', + Symbol = 'symbol' +} + export type Transfer = { __typename?: 'Transfer'; blockNumber: Scalars['BigInt']['output']; @@ -4631,6 +5796,209 @@ export enum Transfer_OrderBy { Value = 'value' } +export type Trove = { + __typename?: 'Trove'; + borrower: Scalars['Bytes']['output']; + closedAt?: Maybe; + collateral: Collateral; + createdAt: Scalars['BigInt']['output']; + debt: Scalars['BigInt']['output']; + deposit: Scalars['BigInt']['output']; + id: Scalars['ID']['output']; + interestBatch?: Maybe; + interestRate: Scalars['BigInt']['output']; + mightBeLeveraged: Scalars['Boolean']['output']; + stake: Scalars['BigInt']['output']; + status: TroveStatus; + troveId: Scalars['String']['output']; + updatedAt: Scalars['BigInt']['output']; +}; + +export enum TroveStatus { + Active = 'active', + Closed = 'closed', + Liquidated = 'liquidated', + Redeemed = 'redeemed' +} + +export type Trove_Filter = { + /** Filter for the block changed event. */ + _change_block?: InputMaybe; + and?: InputMaybe>>; + borrower?: InputMaybe; + borrower_contains?: InputMaybe; + borrower_gt?: InputMaybe; + borrower_gte?: InputMaybe; + borrower_in?: InputMaybe>; + borrower_lt?: InputMaybe; + borrower_lte?: InputMaybe; + borrower_not?: InputMaybe; + borrower_not_contains?: InputMaybe; + borrower_not_in?: InputMaybe>; + closedAt?: InputMaybe; + closedAt_gt?: InputMaybe; + closedAt_gte?: InputMaybe; + closedAt_in?: InputMaybe>; + closedAt_lt?: InputMaybe; + closedAt_lte?: InputMaybe; + closedAt_not?: InputMaybe; + closedAt_not_in?: InputMaybe>; + collateral?: InputMaybe; + collateral_?: InputMaybe; + collateral_contains?: InputMaybe; + collateral_contains_nocase?: InputMaybe; + collateral_ends_with?: InputMaybe; + collateral_ends_with_nocase?: InputMaybe; + collateral_gt?: InputMaybe; + collateral_gte?: InputMaybe; + collateral_in?: InputMaybe>; + collateral_lt?: InputMaybe; + collateral_lte?: InputMaybe; + collateral_not?: InputMaybe; + collateral_not_contains?: InputMaybe; + collateral_not_contains_nocase?: InputMaybe; + collateral_not_ends_with?: InputMaybe; + collateral_not_ends_with_nocase?: InputMaybe; + collateral_not_in?: InputMaybe>; + collateral_not_starts_with?: InputMaybe; + collateral_not_starts_with_nocase?: InputMaybe; + collateral_starts_with?: InputMaybe; + collateral_starts_with_nocase?: InputMaybe; + createdAt?: InputMaybe; + createdAt_gt?: InputMaybe; + createdAt_gte?: InputMaybe; + createdAt_in?: InputMaybe>; + createdAt_lt?: InputMaybe; + createdAt_lte?: InputMaybe; + createdAt_not?: InputMaybe; + createdAt_not_in?: InputMaybe>; + debt?: InputMaybe; + debt_gt?: InputMaybe; + debt_gte?: InputMaybe; + debt_in?: InputMaybe>; + debt_lt?: InputMaybe; + debt_lte?: InputMaybe; + debt_not?: InputMaybe; + debt_not_in?: InputMaybe>; + deposit?: InputMaybe; + deposit_gt?: InputMaybe; + deposit_gte?: InputMaybe; + deposit_in?: InputMaybe>; + deposit_lt?: InputMaybe; + deposit_lte?: InputMaybe; + deposit_not?: InputMaybe; + deposit_not_in?: InputMaybe>; + id?: InputMaybe; + id_gt?: InputMaybe; + id_gte?: InputMaybe; + id_in?: InputMaybe>; + id_lt?: InputMaybe; + id_lte?: InputMaybe; + id_not?: InputMaybe; + id_not_in?: InputMaybe>; + interestBatch?: InputMaybe; + interestBatch_?: InputMaybe; + interestBatch_contains?: InputMaybe; + interestBatch_contains_nocase?: InputMaybe; + interestBatch_ends_with?: InputMaybe; + interestBatch_ends_with_nocase?: InputMaybe; + interestBatch_gt?: InputMaybe; + interestBatch_gte?: InputMaybe; + interestBatch_in?: InputMaybe>; + interestBatch_lt?: InputMaybe; + interestBatch_lte?: InputMaybe; + interestBatch_not?: InputMaybe; + interestBatch_not_contains?: InputMaybe; + interestBatch_not_contains_nocase?: InputMaybe; + interestBatch_not_ends_with?: InputMaybe; + interestBatch_not_ends_with_nocase?: InputMaybe; + interestBatch_not_in?: InputMaybe>; + interestBatch_not_starts_with?: InputMaybe; + interestBatch_not_starts_with_nocase?: InputMaybe; + interestBatch_starts_with?: InputMaybe; + interestBatch_starts_with_nocase?: InputMaybe; + interestRate?: InputMaybe; + interestRate_gt?: InputMaybe; + interestRate_gte?: InputMaybe; + interestRate_in?: InputMaybe>; + interestRate_lt?: InputMaybe; + interestRate_lte?: InputMaybe; + interestRate_not?: InputMaybe; + interestRate_not_in?: InputMaybe>; + mightBeLeveraged?: InputMaybe; + mightBeLeveraged_in?: InputMaybe>; + mightBeLeveraged_not?: InputMaybe; + mightBeLeveraged_not_in?: InputMaybe>; + or?: InputMaybe>>; + stake?: InputMaybe; + stake_gt?: InputMaybe; + stake_gte?: InputMaybe; + stake_in?: InputMaybe>; + stake_lt?: InputMaybe; + stake_lte?: InputMaybe; + stake_not?: InputMaybe; + stake_not_in?: InputMaybe>; + status?: InputMaybe; + status_in?: InputMaybe>; + status_not?: InputMaybe; + status_not_in?: InputMaybe>; + troveId?: InputMaybe; + troveId_contains?: InputMaybe; + troveId_contains_nocase?: InputMaybe; + troveId_ends_with?: InputMaybe; + troveId_ends_with_nocase?: InputMaybe; + troveId_gt?: InputMaybe; + troveId_gte?: InputMaybe; + troveId_in?: InputMaybe>; + troveId_lt?: InputMaybe; + troveId_lte?: InputMaybe; + troveId_not?: InputMaybe; + troveId_not_contains?: InputMaybe; + troveId_not_contains_nocase?: InputMaybe; + troveId_not_ends_with?: InputMaybe; + troveId_not_ends_with_nocase?: InputMaybe; + troveId_not_in?: InputMaybe>; + troveId_not_starts_with?: InputMaybe; + troveId_not_starts_with_nocase?: InputMaybe; + troveId_starts_with?: InputMaybe; + troveId_starts_with_nocase?: InputMaybe; + updatedAt?: InputMaybe; + updatedAt_gt?: InputMaybe; + updatedAt_gte?: InputMaybe; + updatedAt_in?: InputMaybe>; + updatedAt_lt?: InputMaybe; + updatedAt_lte?: InputMaybe; + updatedAt_not?: InputMaybe; + updatedAt_not_in?: InputMaybe>; +}; + +export enum Trove_OrderBy { + Borrower = 'borrower', + ClosedAt = 'closedAt', + Collateral = 'collateral', + CollateralCollIndex = 'collateral__collIndex', + CollateralDebtLimit = 'collateral__debtLimit', + CollateralId = 'collateral__id', + CollateralMinCollRatio = 'collateral__minCollRatio', + CreatedAt = 'createdAt', + Debt = 'debt', + Deposit = 'deposit', + Id = 'id', + InterestBatch = 'interestBatch', + InterestBatchAnnualInterestRate = 'interestBatch__annualInterestRate', + InterestBatchAnnualManagementFee = 'interestBatch__annualManagementFee', + InterestBatchBatchManager = 'interestBatch__batchManager', + InterestBatchColl = 'interestBatch__coll', + InterestBatchDebt = 'interestBatch__debt', + InterestBatchId = 'interestBatch__id', + InterestRate = 'interestRate', + MightBeLeveraged = 'mightBeLeveraged', + Stake = 'stake', + Status = 'status', + TroveId = 'troveId', + UpdatedAt = 'updatedAt' +} + export type Uri = { __typename?: 'URI'; blockNumber: Scalars['BigInt']['output']; @@ -4854,6 +6222,13 @@ export type BalancesForHoldersQueryVariables = Exact<{ export type BalancesForHoldersQuery = { __typename?: 'Query', balances: Array<{ __typename?: 'Balance', holder: string, token: string, balance: bigint }> }; +export type AllocationsQueryVariables = Exact<{ + users: Array | Scalars['Bytes']['input']; +}>; + + +export type AllocationsQuery = { __typename?: 'Query', allocations: Array<{ __typename?: 'Allocation', user: string, activities: Array<{ __typename?: 'Activity', label: string }> }> }; + export class TypedDocumentString extends String implements DocumentTypeDecoration @@ -4890,4 +6265,14 @@ export const BalancesForHoldersDocument = new TypedDocumentString(` balance } } - `) as unknown as TypedDocumentString; \ No newline at end of file + `) as unknown as TypedDocumentString; +export const AllocationsDocument = new TypedDocumentString(` + query Allocations($users: [Bytes!]!) { + allocations(where: {user_in: $users}) { + user + activities { + label + } + } +} + `) as unknown as TypedDocumentString; \ No newline at end of file diff --git a/frontend/app/src/shell-hooks.ts b/frontend/app/src/shell-hooks.ts index 85ce2a5e7..a66858c75 100644 --- a/frontend/app/src/shell-hooks.ts +++ b/frontend/app/src/shell-hooks.ts @@ -6,6 +6,7 @@ import { graphQuery, BalancesByTokenQuery, BalancesForHoldersQuery, + AllocationsQuery, } from "./shell-queries"; import { CONTRACT_SHELL_TOKEN } from "./env"; import { getUniswapPositionsByOwners, PoolKey } from "./uniswap-hooks"; @@ -14,7 +15,7 @@ import { useWagmiConfig } from "@/src/services/Arbitrum"; import { CONTRACT_ADDRESSES } from "./contracts"; import { UniswapV4PositionManager } from "./abi/UniswapV4PositionManager"; import { Abi } from "abitype"; -import { isAddressEqual, zeroAddress } from "viem"; +import { getAddress, isAddressEqual, zeroAddress } from "viem"; type Options = { refetchInterval?: number; @@ -106,4 +107,61 @@ export function useShellActivitiesOfHolders( enabled: Boolean(holders && holders.length > 0), ...prepareOptions(options), }); +} + +export function useAllocations( + users?: Address[], + options?: Options, +) { + const config = useWagmiConfig(); + let queryFn = async () => { + const { allocations } = await graphQuery( + AllocationsQuery, + { users: users?.map(String) ?? [] }, + ); + + const positions = await getUniswapPositionsByOwners(users ?? []); + console.log("positions", positions); + + const existingOwners = new Set(); + const uniswapV4Positions = positions ? (await readContracts(config, { + allowFailure: false, + contracts: positions.map((position) => ({ + address: CONTRACT_ADDRESSES.strategies.UniswapV4 as Address, + abi: UniswapV4PositionManager as Abi, + functionName: "getPoolAndPositionInfo", + args: [position.tokenId], + })), + }) as [PoolKey, bigint][]) + .map(([poolKey], i) => ({ + poolKey, + ...positions[i] + })) + .filter( + ({ poolKey, owner }) => { + const valid = (isAddressEqual(poolKey.currency0, CONTRACT_ADDRESSES.BoldToken) || isAddressEqual(poolKey.currency1, CONTRACT_ADDRESSES.BoldToken)) + && owner !== zeroAddress + if (valid && owner && !existingOwners.has(owner.toLowerCase())) { + existingOwners.add(owner.toLowerCase()); + return true; + } + return false; + } + ) : [] + + return allocations.map(allo => { + const exists = !!uniswapV4Positions.find(position => position.owner && isAddressEqual(getAddress(position.owner!), getAddress(allo.user))); + return { + ...allo, + activities: exists ? [...allo.activities, { label: "Uniswap" }] : allo.activities, + } + }); + }; + + return useQuery({ + queryKey: ["Allocations", users], + queryFn, + enabled: Boolean(users && users.length > 0), + ...prepareOptions(options), + }); } \ No newline at end of file diff --git a/frontend/app/src/shell-queries.ts b/frontend/app/src/shell-queries.ts index c676b1e76..d30e2e5c8 100644 --- a/frontend/app/src/shell-queries.ts +++ b/frontend/app/src/shell-queries.ts @@ -59,4 +59,15 @@ export const BalancesForHoldersQuery = graphql(` balance } } +`) + +export const AllocationsQuery = graphql(` + query Allocations($users: [Bytes!]!) { + allocations( + where: { user_in: $users } + ) { + user + activities { label } + } + } `) \ No newline at end of file diff --git a/frontend/app/src/shellpoints/lib/index.ts b/frontend/app/src/shellpoints/lib/index.ts deleted file mode 100644 index 5191087d1..000000000 --- a/frontend/app/src/shellpoints/lib/index.ts +++ /dev/null @@ -1,175 +0,0 @@ -// import { getTokenHolders } from "./tokenholders" -import { CONTRACT_ADDRESSES } from "@/src/contracts" -import { Address, getAddress, isAddressEqual } from "viem" -import { getGoSlowNftHolders } from "./go-slow-nft" -// import { getTrovesAndOwners } from "./troves" -// import { getAllHistoricalStabilityPoolDepositors } from "./stability-pool" -import { getAssetTransfers, getRecipientsFromAssetTransfers, getStabilityPoolDepositsFromAssetTransfers, getTokenHoldersViaAlchemyAPI } from "./tokenholders" -import { GRAPH_TOKEN_API_TOKEN } from "../utils/env" -import { queryTrovesServerSide } from "./troves" -import { NULL_ADDRESS } from "../utils/constants" - -const addresses = { - usnd: getAddress(CONTRACT_ADDRESSES.BoldToken), - shellPoints: getAddress(CONTRACT_ADDRESSES.ShellToken), - yusnd: getAddress(CONTRACT_ADDRESSES.YUSND), - balancer: getAddress(CONTRACT_ADDRESSES.strategies.Balancer), - camelot: getAddress(CONTRACT_ADDRESSES.strategies.Camelot), - bunni: getAddress(CONTRACT_ADDRESSES.strategies.Bunni), - spectra: getAddress(CONTRACT_ADDRESSES.strategies.Spectra), -} - -export async function queryShellpointsAndActivity() { - const shellTransfers = await getAssetTransfers({ - tokenAddresses: [addresses.shellPoints], - }) - const shellRecipients = getRecipientsFromAssetTransfers(shellTransfers)[addresses.shellPoints] ?? [] - const deposits = await getAssetTransfers({ - tokenAddresses: [addresses.usnd], - toAddresses: CONTRACT_ADDRESSES.collaterals.map(coll => coll.contracts.StabilityPool), - fromAddresses: shellRecipients.map(recipient => recipient.to), - }) - const depositors = getStabilityPoolDepositsFromAssetTransfers(deposits) - - const balances = await getTokenHoldersViaAlchemyAPI({ - tokenAddresses: [addresses.shellPoints], - }) - - const holders = await getTokenHoldersViaTokenAPI({ - token: [addresses.balancer, addresses.bunni, addresses.camelot, addresses.spectra, addresses.yusnd], - }) - - return { - shellPoints: balances.filter(lp => isAddressEqual(lp.token, addresses.shellPoints) && isValidHolder(lp.holder, lp.balance)), - activities: { - yusnd: holders.filter((lp: Holder) => isAddressEqual(lp.token, addresses.yusnd) && isValidHolder(lp.address, lp.amount)), - balancer: holders.filter((lp: Holder) => isAddressEqual(lp.token, addresses.balancer) && isValidHolder(lp.address, lp.amount)), - bunni: holders.filter((lp: Holder) => isAddressEqual(lp.token, addresses.bunni) && isValidHolder(lp.address, lp.amount)), - camelot: holders.filter((lp: Holder) => isAddressEqual(lp.token, addresses.camelot) && isValidHolder(lp.address, lp.amount)), - spectra: holders.filter((lp: Holder) => isAddressEqual(lp.token, addresses.spectra) && isValidHolder(lp.address, lp.amount)), - goSlowNft: await getGoSlowNftHolders(), - troves: await queryTrovesServerSide(), - stabilityPoolDeposits: depositors, - } - } -} - -export async function getAllUsers() { - const holders = await getHolders(); - const protocolUsers = await getProtocolUsers(); - - return { - ...holders, - ...protocolUsers, - } -} - -type TokenHolder = { - block_num: number - last_balance_update: string - address: Address - amount: string - value: number - name: string - decimals: number - symbol: string - network_id: string -} - -type Holder = TokenHolder & { - token: Address -} - -export async function getTokenHoldersViaTokenAPI(params: { - token: Address | Address[] -}) { - const options = { - method: 'GET', - headers: {Authorization: `Bearer ${GRAPH_TOKEN_API_TOKEN}`} - }; - - if (Array.isArray(params.token)) { - const responses = await Promise.all(params.token.map(async (token) => { - const response = await fetch(`https://token-api.thegraph.com/holders/evm/${token}?network_id=arbitrum-one&orderBy=value&orderDirection=desc&limit=1000`, options) - const data = await response.json() - return data.data as TokenHolder[] - })) - return responses.map((response, index) => response.map(holder => ({ - token: params.token[index], - ...holder - }))).flat() as Holder[] - } - const response = await fetch(`https://token-api.thegraph.com/holders/evm/${params.token}?network_id=arbitrum-one&orderBy=value&orderDirection=desc&limit=1000`, options) - const data = (await response.json()).data as TokenHolder[] - return data.map((holder: TokenHolder) => ({ - token: params.token, - ...holder - })) as Holder[] -} - -export async function getHolders() { - const shellPointsHolders = await getTokenHoldersViaAlchemyAPI({ - tokenAddresses: [addresses.shellPoints], - }) - if (shellPointsHolders.length === 0) { - return { - shellPoints: [], - yusnd: [], - balancer: [], - bunni: [], - camelot: [], - spectra: [], - goSlowNft: [], - } - } - const holders = await getTokenHoldersViaTokenAPI({ - token: Object.values(addresses).filter(address => address !== addresses.shellPoints), - }) - const goSlowNftHolders = await getGoSlowNftHolders() - - return { - // shellPoints: holders.filter((lp: Holder) => isAddressEqual(lp.token, addresses.shellPoints) && isNotPool(lp)), - shellPoints: shellPointsHolders.filter(lp => isNotPool({ address: lp.holder, amount: lp.balance })), - yusnd: holders.filter((lp: Holder) => isAddressEqual(lp.token, addresses.yusnd) && isNotPool({ address: lp.address, amount: lp.amount })), - balancer: holders.filter((lp: Holder) => isAddressEqual(lp.token, addresses.balancer) && isNotPool({ address: lp.address, amount: lp.amount })), - bunni: holders.filter((lp: Holder) => isAddressEqual(lp.token, addresses.bunni) && isNotPool({ address: lp.address, amount: lp.amount })), - camelot: holders.filter((lp: Holder) => isAddressEqual(lp.token, addresses.camelot) && isNotPool({ address: lp.address, amount: lp.amount })), - spectra: holders.filter((lp: Holder) => isAddressEqual(lp.token, addresses.spectra) && isNotPool({ address: lp.address, amount: lp.amount })), - goSlowNft: goSlowNftHolders, - } -} - -export async function getProtocolUsers() { - const troves = await queryTrovesServerSide(); - console.log("Retrieved troves:", troves.length); - // console.log("Getting protocol users"); - // const troves = await getTrovesAndOwners(); - // console.log("Retrieved troves"); - // const stabilityPoolDepositors = await getAllHistoricalStabilityPoolDepositors(); - // console.log("Retrieved stability pool depositors"); - - return { - troves, - // stabilityPoolDepositors, - } -} - -function isValidHolder(address: Address, amount?: bigint | string | number) { - return !isAddressEqual(address, NULL_ADDRESS) - && !isAddressEqual(address, addresses.balancer) - && !isAddressEqual(address, addresses.bunni) - && !isAddressEqual(address, addresses.camelot) - && !isAddressEqual(address, addresses.spectra) - && !isAddressEqual(address, addresses.yusnd) - && CONTRACT_ADDRESSES.collaterals.findIndex(coll => isAddressEqual(coll.contracts.StabilityPool, address)) === -1 - && (amount ? BigInt(amount) > 0 : true) -} - -function isNotPool(holder: { address: Address; amount?: bigint | string | number }) { - return (holder.amount ? BigInt(holder.amount) : 0n) > 0n - && !isAddressEqual(holder.address, addresses.balancer) - && !isAddressEqual(holder.address, addresses.bunni) - && !isAddressEqual(holder.address, addresses.camelot) - && !isAddressEqual(holder.address, addresses.spectra) - && !isAddressEqual(holder.address, addresses.yusnd) -} \ No newline at end of file diff --git a/frontend/app/src/shellpoints/lib/troves.ts b/frontend/app/src/shellpoints/lib/troves.ts index 7203b8bef..1079ef676 100644 --- a/frontend/app/src/shellpoints/lib/troves.ts +++ b/frontend/app/src/shellpoints/lib/troves.ts @@ -12,16 +12,7 @@ // import { getCollToken, getPrefixedTroveId, parsePrefixedTroveId } from "@/src/shellpoints/utils/formatting"; // import { getPublicClient } from "@/src/shellpoints/utils/client"; // import { getContracts } from "@/src/contracts"; -import { graphQuery, graphQueryServerSide, TrovesQuery } from "@/src/subgraph-queries"; - -export async function queryTrovesServerSide(params?: {fromTimestamp?: number, toTimestamp?: number}) { - const { troves } = await graphQueryServerSide(TrovesQuery); - if (!params) return troves; - return troves.filter((trove) => { - const { createdAt, closedAt } = trove - return (closedAt ? Number(closedAt) >= (params?.fromTimestamp ?? 0) : true) && (Number(createdAt) >= (params?.fromTimestamp ?? 0)) && (params?.toTimestamp ? Number(createdAt) <= params.toTimestamp : true) - }); -} +import { graphQuery, TrovesQuery } from "@/src/subgraph-queries"; export async function queryTroves(params?: {fromTimestamp?: number, toTimestamp?: number}) { const { troves } = await graphQuery(TrovesQuery); diff --git a/frontend/app/src/subgraph-queries.ts b/frontend/app/src/subgraph-queries.ts index a49632613..b0be1b40d 100644 --- a/frontend/app/src/subgraph-queries.ts +++ b/frontend/app/src/subgraph-queries.ts @@ -1,6 +1,6 @@ import type { TypedDocumentString } from "@/src/graphql/graphql"; -import { SUBGRAPH_URL, SUBGRAPH_URL_SERVER } from "@/src/env"; +import { SUBGRAPH_URL } from "@/src/env"; import { graphql } from "@/src/graphql"; export async function graphQuery( @@ -32,35 +32,6 @@ export async function graphQuery( return result.data as TResult; } -export async function graphQueryServerSide( - query: TypedDocumentString, - ...[variables]: TVariables extends Record ? [] : [TVariables] -) { - const response = await fetch(SUBGRAPH_URL_SERVER, { - method: "POST", - headers: { - "Content-Type": "application/json", - Accept: "application/graphql-response+json", - }, - body: JSON.stringify( - { query, variables }, - (_, value) => typeof value === "bigint" ? String(value) : value, - ), - }); - - if (!response.ok) { - throw new Error("Error while fetching data from the subgraph"); - } - - const result = await response.json(); - - if (!result.data) { - throw new Error("Invalid response from the subgraph"); - } - - return result.data as TResult; -} - export const BorrowerInfoQuery = graphql(` query BorrowerInfo($id: ID!) { borrowerInfo(id: $id) {