Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add USD prices #12

Merged
merged 11 commits into from
Dec 4, 2024
45 changes: 37 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
"@mantine/hooks": "^7.13.3",
"@solana/web3.js": "^2.0.0-rc.1",
"@tabler/icons-react": "^3.19.0",
"@tanstack/react-query": "^5.61.0",
"@tanstack/query-persist-client-core": "^5.62.0",
"@tanstack/query-sync-storage-persister": "^5.62.0",
"@tanstack/react-query": "^5.62.0",
"jdenticon": "^3.3.0",
"js-big-decimal": "^2.1.0",
"react": "^18.3.1",
Expand Down
5 changes: 5 additions & 0 deletions src/jupiter-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export async function getClosedDCAs(address: Address) {
return queryClient.fetchQuery({
queryKey: ["closedDCAs", address],
queryFn: () => getClosedDCAsImpl(address),
staleTime: 5 * 60 * 1000, // 5 minutes
});
}

Expand All @@ -42,6 +43,7 @@ export async function getOpenDCAs(address: Address) {
return queryClient.fetchQuery({
queryKey: ["openDCAs", address],
queryFn: () => getOpenDCAsImpl(address),
staleTime: 5 * 60 * 1000, // 5 minutes
});
}

Expand All @@ -60,6 +62,7 @@ export async function getClosedValueAverages(address: Address) {
return queryClient.fetchQuery({
queryKey: ["closedValueAverages", address],
queryFn: () => getClosedValueAveragesImpl(address),
staleTime: 5 * 60 * 1000, // 5 minutes
});
}

Expand All @@ -78,6 +81,7 @@ export async function getOpenValueAverages(address: Address) {
return queryClient.fetchQuery({
queryKey: ["openValueAverages", address],
queryFn: () => getOpenValueAveragesImpl(address),
staleTime: 5 * 60 * 1000, // 5 minutes
});
}

Expand Down Expand Up @@ -113,5 +117,6 @@ export async function getLimitOrdersWithTrades(address: Address) {
return queryClient.fetchQuery({
queryKey: ["limitOrdersWithTrades", address],
queryFn: () => getLimitOrdersWithTradesImpl(address),
staleTime: 5 * 60 * 1000, // 5 minutes
});
}
5 changes: 5 additions & 0 deletions src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import StrategiesRoute, {
} from "./routes/strategies";
import TradesRoute, { loader as TradesLoader } from "./routes/trades";
import { action as TradesCsvAction } from "./routes/trades-csv";
import { action as FetchUsdPricesAction } from "./routes/fetch-usd-prices";
import { createTheme, MantineProvider } from "@mantine/core";

import "@mantine/core/styles.css";
Expand Down Expand Up @@ -38,6 +39,10 @@ const router = createBrowserRouter([
path: "/trades/csv",
action: TradesCsvAction,
},
{
path: "/trades/fetch-usd-prices",
action: FetchUsdPricesAction,
},
],
},
]);
Expand Down
24 changes: 24 additions & 0 deletions src/number-display.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,27 @@ export function numberDisplayAlreadyAdjustedForDecimals(
// we use the formatter to get better display, eg `123456` -> `123,456`
return formatter.format(`${value}`);
}

const usdTwoDecimalsFormatter = Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
minimumFractionDigits: 2,
maximumFractionDigits: 2,
});

const usdEightDecimalsFormatter = Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
minimumFractionDigits: 2,
maximumFractionDigits: 8,
});

export function usdAmountDisplay(value: number) {
if (value < 0.00000001) {
return "<$0.00000001";
}

const formatter =
value < 1 ? usdEightDecimalsFormatter : usdTwoDecimalsFormatter;
return formatter.format(value);
}
16 changes: 15 additions & 1 deletion src/query-client.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
import { QueryClient } from "@tanstack/react-query";
import { persistQueryClient } from "@tanstack/query-persist-client-core";
import { createSyncStoragePersister } from "@tanstack/query-sync-storage-persister";

export const queryClient = new QueryClient();
queryClient.setDefaultOptions({
// used for restored data
queries: {
staleTime: 1000 * 60 * 5, // 5 minutes
staleTime: Infinity,
gcTime: Infinity,
},
});

const persister = createSyncStoragePersister({
storage: window.localStorage,
key: "react-query-cache",
});

persistQueryClient({
queryClient,
persister,
});
38 changes: 38 additions & 0 deletions src/routes/fetch-usd-prices.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { ActionFunctionArgs } from "react-router-dom";
import { fetchTokenPrices } from "../token-prices";
import { TokenPricesToFetch } from "../types";

export async function action({ request }: ActionFunctionArgs) {
const formData = await request.formData();
const birdeyeApiKey = formData.get("birdeyeApiKey")?.toString();
const rememberApiKeyValue = formData.get("rememberApiKey")?.toString();
const rememberApiKey = rememberApiKeyValue === "on";

if (!birdeyeApiKey) {
throw new Error("Birdeye API key is required");
}

const tokenPricesToFetchField = formData.get("tokenPricesToFetch");

if (!tokenPricesToFetchField) {
throw new Error("Token prices to fetch is required");
}

const tokenPricesToFetch = JSON.parse(
tokenPricesToFetchField.toString(),
) as TokenPricesToFetch;

const tokenPrices = await fetchTokenPrices(
tokenPricesToFetch,
birdeyeApiKey,
request.signal,
);

if (rememberApiKey) {
localStorage.setItem("birdeyeApiKey", birdeyeApiKey);
} else {
localStorage.removeItem("birdeyeApiKey");
}

return tokenPrices;
}
Loading
Loading