Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
carina-akaia committed Jun 19, 2024
1 parent 021764f commit f1d5337
Show file tree
Hide file tree
Showing 10 changed files with 147 additions and 28 deletions.
15 changes: 15 additions & 0 deletions src/common/api/coingecko/hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import useSWR from "swr";

import { COINGECKO_API_ENDPOINT } from "../../constants";

const fetcher = (url: string) =>
fetch(COINGECKO_API_ENDPOINT + url).then((res) => res.json());

const fetcherWithTransform = (transform: Function) => (url: string) =>
fetcher(url).then((data) => transform(data));

export const useOneNearUsdPrice = () =>
useSWR(
"/simple/price?ids=near&vs_currencies=usd",
fetcherWithTransform((response: any) => response.near.usd),
);
1 change: 1 addition & 0 deletions src/common/api/coingecko/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * as coingecko from "./hooks";
4 changes: 4 additions & 0 deletions src/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ export const PAGODA_REQUEST_CONFIG = {
},
};

export const COINGECKO_API_ENDPOINT = "https://api.coingecko.com/api/v3";

// SYBIL CONTRACT
export const NADABOT_CONTRACT_ID = process.env
.NEXT_PUBLIC_NADABOT_CONTRACT_ID as string;
Expand All @@ -70,6 +72,8 @@ export const POTLOCK_REGISTRY_LIST_ID = 1;

export const NEAR_TOKEN_DENOM = "near";

export const NEAR_DEFAULT_TOKEN_DECIMALS = 24;

// 1 NEAR
export const ONE_NEAR = utils.format.parseNearAmount("1")!;
// 0.5 NEAR
Expand Down
19 changes: 19 additions & 0 deletions src/common/lib/converters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import Big from "big.js";

import formatWithCommas from "./formatWithCommas";
import { NEAR_DEFAULT_TOKEN_DECIMALS } from "../constants";

export const yoctosToNear = (amountYoctos: string, abbreviate?: boolean) => {
return (
formatWithCommas(Big(amountYoctos).div(1e24).toFixed(2)) +
(abbreviate ? "N" : " NEAR")
);
};

export const bigNumToFloat = (amount: string, decimals: number) => {
const decimalMultiplier = Big(10).pow(decimals);
return parseFloat(Big(amount).div(decimalMultiplier).toFixed(2));
};

export const yoctoNearToFloat = (amountYoctoNear: string) =>
bigNumToFloat(amountYoctoNear, NEAR_DEFAULT_TOKEN_DECIMALS);
2 changes: 1 addition & 1 deletion src/common/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export * from "./_address";
export * from "./yoctosToNear";
export * from "./converters";
10 changes: 0 additions & 10 deletions src/common/lib/yoctosToNear.ts

This file was deleted.

8 changes: 6 additions & 2 deletions src/common/ui/components/text-field.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export interface TextFieldProps
label: string;
labelExtension?: React.ReactNode;
fieldExtension?: React.ReactNode;
appendix?: string;
appendix?: string | null;
}

export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
Expand Down Expand Up @@ -71,13 +71,17 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
{fieldExtensionElement}

<input
className={cn({
"rounded-l-lg": fieldExtensionElement === null,
"mr-1 rounded-r-lg": appendixElement === null,
})}
un-focus-visible={
fieldExtensionElement !== null && appendixElement !== null
? "border-inset pl-1.5 border-l-2 border-input outline-none"
: undefined
}
un-pl={fieldExtensionElement === null ? "3" : "1.5"}
un-pr={appendixElement === null ? "3" : "1.5"}
un-pr="1.5"
un-w="full"
un-h="9"
un-placeholder="text-muted-foreground"
Expand Down
25 changes: 25 additions & 0 deletions src/modules/core/hooks/price.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { useMemo } from "react";

import { coingecko } from "@/common/api/coingecko";
import { NEAR_DEFAULT_TOKEN_DECIMALS } from "@/common/constants";
import { bigNumToFloat } from "@/common/lib";
import formatWithCommas from "@/common/lib/formatWithCommas";

export const useYoctoNearUsdDisplayValue = (
amountYoctoNear: string,
): string => {
const { data: oneNearUsdPrice } = coingecko.useOneNearUsdPrice();

return useMemo(
() =>
`~$ ${formatWithCommas(
(oneNearUsdPrice
? bigNumToFloat(amountYoctoNear, NEAR_DEFAULT_TOKEN_DECIMALS) *
oneNearUsdPrice
: 0.0
).toString(),
)}`,

[amountYoctoNear, oneNearUsdPrice],
);
};
13 changes: 13 additions & 0 deletions src/modules/core/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import Big from "big.js";

import { NearBalanceResponse } from "@/common/api/pagoda/generated";
import { bigNumToFloat } from "@/common/lib";
import formatWithCommas from "@/common/lib/formatWithCommas";
import { fetchNearPrice } from "@/common/services";

Expand All @@ -17,3 +19,14 @@ export const yoctosToUsdWithFallback = async (
: formatWithCommas(Big(amountYoctos).div(1e24).toFixed(2)) +
(abbreviate ? "N" : " NEAR");
};

export const balanceToFloat = (
amount: NearBalanceResponse["balance"]["amount"],
decimals: NearBalanceResponse["balance"]["metadata"]["decimals"],
) => bigNumToFloat(amount, decimals);

export const balanceToString = ({
amount,
metadata,
}: NearBalanceResponse["balance"]) =>
`${balanceToFloat(amount, metadata.decimals)} ${metadata.symbol}`;
78 changes: 63 additions & 15 deletions src/modules/donation/components/DonationProjectAllocation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { pagoda } from "@/common/api/pagoda";
import { ByAccountId, potlock } from "@/common/api/potlock";
import { NEAR_TOKEN_DENOM } from "@/common/constants";
import { walletApi } from "@/common/contracts";
import { bigNumToFloat } from "@/common/lib";
import {
DialogDescription,
DialogHeader,
Expand All @@ -25,7 +26,12 @@ import {
SelectValue,
TextField,
} from "@/common/ui/components";
import { RuntimeErrorAlert } from "@/modules/core";
import {
RuntimeErrorAlert,
balanceToFloat,
balanceToString,
} from "@/modules/core";
import { useYoctoNearUsdDisplayValue } from "@/modules/core/hooks/price";

import { DONATION_MIN_NEAR_AMOUNT } from "../constants";
import {
Expand Down Expand Up @@ -82,6 +88,22 @@ export const DonationProjectAllocation: React.FC<
[availableFtBalances, availableNearBalance, isFtDonation, tokenId],
);

const availableBalanceFloat = useMemo(
() =>
availableBalance === null
? null
: balanceToFloat(
availableBalance?.amount,
availableBalance?.metadata.decimals,
),

[availableBalance],
);

const availableNearBalanceUsdDisplayValue = useYoctoNearUsdDisplayValue(
availableNearBalance?.amount ?? "0",
);

return isAccountLoading || isNearBalanceLoading || isFtBalanceLoading ? (
<span
un-flex="~"
Expand Down Expand Up @@ -161,7 +183,7 @@ export const DonationProjectAllocation: React.FC<
un-text="sm neutral-950"
un-font="600"
>
{`${availableBalance.amount} ${availableBalance.metadata.symbol}`}
{balanceToString(availableBalance)}
</span>

<span className="prose" un-text="sm neutral-600">
Expand All @@ -171,26 +193,52 @@ export const DonationProjectAllocation: React.FC<
)
}
fieldExtension={
<Select defaultValue={tokenIdSchema.parse(tokenId)}>
<SelectTrigger className="h-full w-min rounded-r-none shadow-none">
<SelectValue />
</SelectTrigger>

<SelectContent>
<SelectGroup>
<SelectLabel>Available tokens</SelectLabel>
<SelectItem value="near">NEAR</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
<FormField
control={form.control}
name="tokenId"
render={({ field: fieldExtension }) => (
<Select
defaultValue={fieldExtension.value}
onValueChange={fieldExtension.onChange}
>
<SelectTrigger className="h-full w-min rounded-r-none shadow-none">
<SelectValue />
</SelectTrigger>

<SelectContent>
<SelectGroup>
<SelectLabel>Available tokens</SelectLabel>

<SelectItem value={NEAR_TOKEN_DENOM}>
{NEAR_TOKEN_DENOM.toUpperCase()}
</SelectItem>

{availableFtBalances?.map(
({
contract_account_id: contractId,
metadata: { symbol },
}) => (
<SelectItem key={contractId} value={contractId}>
{symbol}
</SelectItem>
),
)}
</SelectGroup>
</SelectContent>
</Select>
)}
/>
}
type="number"
placeholder="0.00"
min={
tokenId === NEAR_TOKEN_DENOM ? DONATION_MIN_NEAR_AMOUNT : 0.0
}
max={availableBalanceFloat ?? undefined}
step={0.01}
appendix="$ 0.00"
appendix={
isFtDonation ? null : availableNearBalanceUsdDisplayValue
}
/>
</DialogDescription>
</>
Expand Down

0 comments on commit f1d5337

Please sign in to comment.