diff --git a/dapp/src/components/Modals/StakeModal.tsx b/dapp/src/components/Modals/StakeModal.tsx index 857e303c3..397943fc1 100644 --- a/dapp/src/components/Modals/StakeModal.tsx +++ b/dapp/src/components/Modals/StakeModal.tsx @@ -10,14 +10,12 @@ import { Tab, TabPanels, TabPanel, - NumberInput, - NumberInputField, - NumberInputStepper, } from "@chakra-ui/react" -import { useStakingFlowContext } from "../../hooks" +import { useStakingFlowContext, useWalletContext } from "../../hooks" import BaseModal from "./BaseModal" import { TokenBalance } from "../TokenBalance" import { BITCOIN } from "../../constants" +import TokenBalanceInput from "../TokenBalanceInput" function StakeDetails({ text, @@ -41,7 +39,8 @@ function StakeDetails({ } export default function ActionModal() { - const { closeModal } = useStakingFlowContext() + const { amount, setAmount, closeModal } = useStakingFlowContext() + const { btcAccount } = useWalletContext() return ( @@ -55,11 +54,16 @@ export default function ActionModal() { - {/* TODO: Create a custom number input component */} - - - - + {/* TODO: Add a validation */} + setAmount(value)} + /> {/* TODO: Use the real data */} void +}) { + // TODO: Set the correct color + const colorInfo = useColorModeValue("grey.200", "grey.200") + + const tokenBalanceAmount = useMemo( + () => + fixedPointNumberToString(BigInt(tokenBalance || 0), currency.decimals), + [currency.decimals, tokenBalance], + ) + + return ( + + + Amount + + Balance + + + + + onChange(valueString)} + > + + + + + + + + {/* TODO: Add correct text for tooltip */} + + + + {`${usdAmount} ${USD.symbol}`} + + + ) +} diff --git a/dapp/src/contexts/StakingFlowContext.tsx b/dapp/src/contexts/StakingFlowContext.tsx index a58446787..94882db3b 100644 --- a/dapp/src/contexts/StakingFlowContext.tsx +++ b/dapp/src/contexts/StakingFlowContext.tsx @@ -2,15 +2,17 @@ import React, { createContext, useCallback, useMemo, useState } from "react" import { ModalType } from "../types" type StakingFlowContextValue = { - modalType: ModalType | undefined + modalType?: ModalType + amount?: string closeModal: () => void setModalType: React.Dispatch> + setAmount: React.Dispatch> } export const StakingFlowContext = createContext({ - modalType: undefined, - setModalType: () => {}, closeModal: () => {}, + setModalType: () => {}, + setAmount: () => {}, }) export function StakingFlowProvider({ @@ -19,19 +21,23 @@ export function StakingFlowProvider({ children: React.ReactNode }): React.ReactElement { const [modalType, setModalType] = useState(undefined) + const [amount, setAmount] = useState(undefined) const closeModal = useCallback(() => { setModalType(undefined) + setAmount(undefined) }, []) const contextValue: StakingFlowContextValue = useMemo( () => ({ modalType, + amount, closeModal, setModalType, + setAmount, }), - [modalType, closeModal], + [modalType, amount, closeModal], ) return ( diff --git a/dapp/src/static/icons/Alert.tsx b/dapp/src/static/icons/Alert.tsx new file mode 100644 index 000000000..129907d49 --- /dev/null +++ b/dapp/src/static/icons/Alert.tsx @@ -0,0 +1,31 @@ +import React from "react" +import { createIcon } from "@chakra-ui/react" + +export const Alert = createIcon({ + displayName: "Alert", + viewBox: "0 0 16 16", + path: ( + + + + + + + + + + + ), +}) diff --git a/dapp/src/static/icons/index.ts b/dapp/src/static/icons/index.ts index 66c6e3aa9..6e64faaba 100644 --- a/dapp/src/static/icons/index.ts +++ b/dapp/src/static/icons/index.ts @@ -2,3 +2,4 @@ export * from "./Info" export * from "./Bitcoin" export * from "./Ethereum" export * from "./ChevronRight" +export * from "./Alert" diff --git a/dapp/src/utils/numbers.ts b/dapp/src/utils/numbers.ts index 1b354687f..f292f41b9 100644 --- a/dapp/src/utils/numbers.ts +++ b/dapp/src/utils/numbers.ts @@ -65,3 +65,42 @@ export const formatSatoshiAmount = ( amount: number | string, desiredDecimals = 2, ) => formatTokenAmount(amount, 8, desiredDecimals) + +/** + * Converts a fixed point number with a bigint amount and a decimals field + * indicating the orders of magnitude in `amount` behind the decimal point into + * a string in US decimal format (no thousands separators, . for the decimal + * separator). + * + * Used in cases where precision is critical. + * + * This function is based on the solution used by the Taho extension. + * More info: https://github.com/tahowallet/extension/blob/main/background/lib/fixed-point.ts#L172-L214 + */ +export function fixedPointNumberToString( + amount: bigint, + decimals: number, + trimTrailingZeros = true, +): string { + const undecimaledAmount = amount.toString() + const preDecimalLength = undecimaledAmount.length - decimals + + const preDecimalCharacters = + preDecimalLength > 0 + ? undecimaledAmount.substring(0, preDecimalLength) + : "0" + const postDecimalCharacters = + "0".repeat(Math.max(-preDecimalLength, 0)) + + undecimaledAmount.substring(preDecimalLength) + + const trimmedPostDecimalCharacters = trimTrailingZeros + ? postDecimalCharacters.replace(/0*$/, "") + : postDecimalCharacters + + const decimalString = + trimmedPostDecimalCharacters.length > 0 + ? `.${trimmedPostDecimalCharacters}` + : "" + + return `${preDecimalCharacters}${decimalString}` +}