diff --git a/components/RoundStatus/index.tsx b/components/RoundStatus/index.tsx
index d4f5bd21..6627fca9 100644
--- a/components/RoundStatus/index.tsx
+++ b/components/RoundStatus/index.tsx
@@ -9,7 +9,7 @@ import {
QuestionMarkCircledIcon,
} from "@modulz/radix-icons";
import { ProtocolQueryResult } from "apollo";
-import { useCurrentRoundData } from "hooks";
+import { useCurrentRoundData, useSupplyChangeData } from "hooks";
import { useTheme } from "next-themes";
import numbro from "numbro";
import { useMemo } from "react";
@@ -77,6 +77,11 @@ const Index = ({
) || 0,
[protocol]
);
+ const totalSupply = useMemo(
+ () => (protocol?.totalSupply ? Number(protocol.totalSupply) : null),
+ [protocol]
+ );
+ const supplyChangeData = useSupplyChangeData();
return (
+
+ The current total supply of LPT.}
+ >
+
+
+
+ Total Supply
+
+
+
+
+
+
+
+ {totalSupply !== null
+ ? `${numbro(totalSupply).format({
+ mantissa: 0,
+ average: true,
+ })} LPT`
+ : "--"}
+
+
+
+ Total supply change over the past 365 days.}
+ >
+
+
+
+ Supply Change (1Y)
+
+
+
+
+
+
+
+ {supplyChangeData?.supplyChange != null
+ ? numbro(supplyChangeData?.supplyChange ?? 0).format({
+ output: "percent",
+ mantissa: 2,
+ })
+ : "--"}
+
+
+
) : (
{
return data ?? null;
};
+export const useSupplyChangeData = () => {
+ const { data } = useSWR(`/supply-change`);
+
+ return data ?? null;
+};
+
export const useAvailableInferencePipelinesData = () => {
const { data, isValidating } = useSWR(`/pipelines`);
return { data: data ?? { pipelines: [] }, isValidating };
diff --git a/lib/api/types/get-supply-change.ts b/lib/api/types/get-supply-change.ts
new file mode 100644
index 00000000..92775650
--- /dev/null
+++ b/lib/api/types/get-supply-change.ts
@@ -0,0 +1,7 @@
+export type SupplyChangeData = {
+ startDate: number;
+ endDate: number;
+ startSupply: number;
+ endSupply: number;
+ supplyChange: number | null;
+};
diff --git a/pages/api/supply-change.tsx b/pages/api/supply-change.tsx
new file mode 100644
index 00000000..35647c17
--- /dev/null
+++ b/pages/api/supply-change.tsx
@@ -0,0 +1,94 @@
+import { getCacheControlHeader } from "@lib/api";
+import type { SupplyChangeData } from "@lib/api/types/get-supply-change";
+import { CHAIN_INFO, DEFAULT_CHAIN_ID } from "@lib/chains";
+import { fetchWithRetry } from "@lib/fetchWithRetry";
+import type { NextApiRequest, NextApiResponse } from "next";
+
+const SECONDS_PER_DAY = 24 * 60 * 60;
+
+const supplyChangeHandler = async (
+ req: NextApiRequest,
+ res: NextApiResponse
+) => {
+ try {
+ const { method } = req;
+ if (method !== "GET") {
+ res.setHeader("Allow", ["GET"]);
+ return res.status(405).end(`Method ${method} Not Allowed`);
+ }
+ res.setHeader("Cache-Control", getCacheControlHeader("day"));
+
+ const rangeStartDate =
+ Math.floor(Date.now() / 1000) - 365 * SECONDS_PER_DAY;
+
+ const response = await fetchWithRetry(
+ CHAIN_INFO[DEFAULT_CHAIN_ID].subgraph,
+ {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({
+ query: `
+ query SupplyChange($rangeStartDate: Int!) {
+ start: days(
+ first: 1
+ orderBy: date
+ orderDirection: asc
+ where: { date_gte: $rangeStartDate }
+ ) {
+ date
+ totalSupply
+ }
+ end: days(
+ first: 1
+ orderBy: date
+ orderDirection: desc
+ where: { date_gte: $rangeStartDate }
+ ) {
+ date
+ totalSupply
+ }
+ }
+ `,
+ variables: {
+ rangeStartDate,
+ },
+ }),
+ },
+ {
+ retryOnMethods: ["POST"],
+ }
+ );
+
+ if (!response.ok) {
+ return res.status(500).json(null);
+ }
+
+ const { data } = await response.json();
+ const start = Array.isArray(data?.start) ? data.start : [];
+ const end = Array.isArray(data?.end) ? data.end : [];
+
+ const startItem = start[0];
+ const endItem = end[0];
+ const startSupply = Number(startItem?.totalSupply ?? 0);
+ const endSupply = Number(endItem?.totalSupply ?? 0);
+ const supplyChange =
+ startSupply > 0 && endSupply > 0
+ ? (endSupply - startSupply) / startSupply
+ : null;
+
+ return res.status(200).json({
+ startDate: Number(startItem?.date ?? 0),
+ endDate: Number(endItem?.date ?? 0),
+ startSupply,
+ endSupply,
+ supplyChange,
+ });
+ } catch (err) {
+ console.error(err);
+ return res.status(500).json(null);
+ }
+};
+
+export default supplyChangeHandler;
diff --git a/pages/api/totalTokenSupply.tsx b/pages/api/totalTokenSupply.tsx
deleted file mode 100644
index 23a19d04..00000000
--- a/pages/api/totalTokenSupply.tsx
+++ /dev/null
@@ -1,37 +0,0 @@
-import { getCacheControlHeader } from "@lib/api";
-import { CHAIN_INFO, DEFAULT_CHAIN_ID } from "@lib/chains";
-import { fetchWithRetry } from "@lib/fetchWithRetry";
-import type { NextApiRequest, NextApiResponse } from "next";
-
-const totalTokenSupply = async (_req: NextApiRequest, res: NextApiResponse) => {
- const response = await fetchWithRetry(
- CHAIN_INFO[DEFAULT_CHAIN_ID].subgraph,
- {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify({
- query: `
- query {
- protocol(id: "0") {
- totalSupply
- }
- }
- `,
- }),
- },
- {
- retryOnMethods: ["POST"],
- }
- );
-
- res.setHeader("Cache-Control", getCacheControlHeader("day"));
-
- const {
- data: { protocol },
- } = await response.json();
- res.json(Number(protocol.totalSupply));
-};
-
-export default totalTokenSupply;
diff --git a/pages/treasury/create-proposal.tsx b/pages/treasury/create-proposal.tsx
index b24a7983..d24fb2ba 100644
--- a/pages/treasury/create-proposal.tsx
+++ b/pages/treasury/create-proposal.tsx
@@ -301,9 +301,9 @@ const CreateProposal = () => {
},
}}
>
-
+
LPT receiver:
-
+