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

Initial implementation of stake form #93

Merged
merged 28 commits into from
Jan 10, 2024
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
7269487
Form initialization for stake/unstake action
kkosiorowska Dec 27, 2023
2fdfae3
Add function to convert user amount to `bigint`
kkosiorowska Dec 28, 2023
e4ccfbe
Add a validation for stake form
kkosiorowska Dec 28, 2023
4c67f66
Handling the submission of the stake form
kkosiorowska Dec 28, 2023
062cadf
Merge branch 'main' into stake-form
kkosiorowska Dec 28, 2023
1b1b9ab
Improvements for forms
kkosiorowska Dec 29, 2023
4b845b9
Define custom data from the form level
kkosiorowska Dec 29, 2023
a1bdfc7
Merge branch 'main' of github.com:thesis/acre into stake-form
kkosiorowska Jan 2, 2024
303f3b2
Make a `validate` function more general
kkosiorowska Jan 2, 2024
c697ec8
Create a utils function to find for currency by type
kkosiorowska Jan 2, 2024
9984076
Make the token amount form component clearer
kkosiorowska Jan 2, 2024
4399b2c
Simplify the ActionForm component
kkosiorowska Jan 3, 2024
8c8d2a1
Store the amount as bigint for the token amount form
kkosiorowska Jan 3, 2024
acda15a
Merge branch 'main' of github.com:thesis/acre into stake-form
kkosiorowska Jan 4, 2024
9eba84c
Update the submit form function for staking
kkosiorowska Jan 8, 2024
a0c4b71
Use a more precise name for custom form data
kkosiorowska Jan 8, 2024
443c881
Refactor the display of transaction details in the form
kkosiorowska Jan 9, 2024
d49a39c
Use `Currency` instead `CurrencyType` for TokenAmountForm
kkosiorowska Jan 9, 2024
99bcdfe
Move conversion logic to `CurrencyBalanceWithConversion` component
kkosiorowska Jan 9, 2024
a28a07f
Refactor for `useTransactionDetails`
kkosiorowska Jan 9, 2024
8f397e2
Fix the positioning bug for `TransactionDetailsAmountItem`
kkosiorowska Jan 9, 2024
720b567
Merge branch 'main' of github.com:thesis/acre into stake-form
kkosiorowska Jan 10, 2024
47c0ca1
Save the token amount field name for the form as const
kkosiorowska Jan 10, 2024
96e87fc
Make a formId optional for the the token amount form
kkosiorowska Jan 10, 2024
cf1eabb
Render the submit button inside form
kkosiorowska Jan 10, 2024
c6b6c7b
Use always `CurrencyType`
kkosiorowska Jan 10, 2024
39cfbbc
Fix typo from `seTokenAmount` to `setTokenAmount`
kkosiorowska Jan 10, 2024
597a890
Create a special hook for the token amount value from form
kkosiorowska Jan 10, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"@emotion/styled": "^11.11.0",
"@ledgerhq/wallet-api-client": "^1.5.0",
"@ledgerhq/wallet-api-client-react": "^1.3.0",
"formik": "^2.4.5",
"framer-motion": "^10.16.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
2 changes: 1 addition & 1 deletion dapp/src/components/Header/ConnectWallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default function ConnectWallet() {
<HStack display={{ base: "none", md: "flex" }}>
<TextMd color="grey.500">Balance</TextMd>
<CurrencyBalance
currencyType="bitcoin"
currency="bitcoin"
amount={btcAccount?.balance.toString()}
/>
</HStack>
Expand Down
41 changes: 41 additions & 0 deletions dapp/src/components/Modals/ActionForm/index.tsx
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about the name of this component because at first sight, it may indicate we can render any form but actually we are rendering stake/unstake form.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's true this name isn't perfect. But I don't have a better idea. You are right, but on the other hand, we are just displaying the form there. The type of action restricts us on the types of form. If you just have any better idea let me know.

Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from "react"
import {
ModalBody,
Tabs,
TabList,
Tab,
TabPanels,
TabPanel,
} from "@chakra-ui/react"
import StakeForm from "../Staking/StakeForm"
import { useModalFlowContext } from "../../../hooks"

const TABS = ["stake", "unstake"] as const

type Action = (typeof TABS)[number]

function ActionForm({ action }: { action: Action }) {
const { goNext } = useModalFlowContext()

return (
<ModalBody>
<Tabs w="100%" variant="underline" defaultIndex={TABS.indexOf(action)}>
<TabList>
{TABS.map((tab) => (
<Tab key={tab} w="50%">
{tab}
</Tab>
))}
</TabList>
<TabPanels>
<TabPanel>
<StakeForm goNext={goNext} />
</TabPanel>
<TabPanel>{/* TODO: Add form for unstake */}</TabPanel>
</TabPanels>
</Tabs>
</ModalBody>
)
}

export default ActionForm
17 changes: 0 additions & 17 deletions dapp/src/components/Modals/Staking/StakeForm.tsx

This file was deleted.

55 changes: 55 additions & 0 deletions dapp/src/components/Modals/Staking/StakeForm/Details.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React from "react"
import { List } from "@chakra-ui/react"
import { useField } from "formik"
import { useTransactionDetails } from "../../../../hooks"
import TransactionDetailsAmountItem from "../../../shared/TransactionDetails/AmountItem"
import { Currency } from "../../../../types"

function Details({
fieldName,
currency,
}: {
fieldName: string
currency: Currency
}) {
const [, { value }] = useField<bigint | undefined>(fieldName)

const details = useTransactionDetails(value ?? 0n)

return (
<List spacing={3} mt={10}>
<TransactionDetailsAmountItem
label="Amount to be staked"
from={{
currency,
amount: details?.btcAmount,
}}
to={{
currency: "usd",
}}
/>
<TransactionDetailsAmountItem
label="Protocol fee (0.01%)"
from={{
currency,
amount: details?.protocolFee,
}}
to={{
currency: "usd",
}}
/>
<TransactionDetailsAmountItem
label="Approximately staked tokens"
from={{
currency,
amount: details?.estimatedAmount,
}}
to={{
currency: "usd",
}}
/>
</List>
)
}

export default Details
47 changes: 47 additions & 0 deletions dapp/src/components/Modals/Staking/StakeForm/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React, { useCallback } from "react"
import { Button } from "@chakra-ui/react"
import { BITCOIN, BITCOIN_MIN_AMOUNT } from "../../../../constants"
import { ModalStep } from "../../../../contexts"
import { useWalletContext, useTransactionContext } from "../../../../hooks"
import TokenAmountForm from "../../../shared/TokenAmountForm"
import { TokenAmountFormValues } from "../../../shared/TokenAmountForm/TokenAmountFormBase"
import Details from "./Details"

const FORM_FIELD_NAME = "amount"
r-czajkowski marked this conversation as resolved.
Show resolved Hide resolved
const FORM_ID = "staking-form"

function StakeForm({ goNext }: ModalStep) {
const { btcAccount } = useWalletContext()
const { seTokenAmount } = useTransactionContext()
r-czajkowski marked this conversation as resolved.
Show resolved Hide resolved

const handleSubmitForm = useCallback(
(values: TokenAmountFormValues) => {
if (!values.amount) return

seTokenAmount({ amount: values.amount, currency: BITCOIN })
goNext()
},
[goNext, seTokenAmount],
)

return (
<>
<TokenAmountForm
formId={FORM_ID}
fieldName={FORM_FIELD_NAME}
tokenBalanceInputPlaceholder="BTC"
currency={BITCOIN}
tokenBalance={btcAccount?.balance.toString() ?? "0"}
minTokenAmount={BITCOIN_MIN_AMOUNT}
onSubmitForm={handleSubmitForm}
>
<Details currency={BITCOIN} fieldName={FORM_FIELD_NAME} />
</TokenAmountForm>
<Button type="submit" form={FORM_ID} size="lg" width="100%" mt={4}>
Stake
</Button>
r-czajkowski marked this conversation as resolved.
Show resolved Hide resolved
</>
)
}

export default StakeForm
4 changes: 2 additions & 2 deletions dapp/src/components/Modals/Staking/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React from "react"
import { useModalFlowContext } from "../../../hooks"
import StakeForm from "./StakeForm"
import Overview from "./Overview"
import ModalBase from "../../shared/ModalBase"
import ActionForm from "../ActionForm"
import SignMessage from "./SignMessage"
import DepositBTC from "./DepositBTC"

Expand All @@ -11,7 +11,7 @@ function ActiveStakingStep() {

switch (activeStep) {
case 1:
return <StakeForm />
return <ActionForm action="stake" />
case 2:
return <Overview />
case 3:
Expand Down
4 changes: 2 additions & 2 deletions dapp/src/components/Modals/Support/MissingAccount.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
import { CurrencyType, RequestAccountParams } from "../../../types"
import { TextMd } from "../../shared/Typography"
import Alert from "../../shared/Alert"
import { CURRENCIES_BY_TYPE } from "../../../constants"
import { getCurrencyByType } from "../../../utils"

type MissingAccountProps = {
currencyType: CurrencyType
Expand All @@ -23,7 +23,7 @@ export default function MissingAccount({
icon,
requestAccount,
}: MissingAccountProps) {
const currency = CURRENCIES_BY_TYPE[currencyType]
const currency = getCurrencyByType(currencyType)

return (
<>
Expand Down
6 changes: 2 additions & 4 deletions dapp/src/components/Overview/PositionDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,12 @@ export default function PositionDetails(props: CardProps) {
</HStack>
<CurrencyBalanceWithConversion
from={{
currencyType: "bitcoin",
currency: "bitcoin",
amount: "2398567898",
variant: "greater-balance",
}}
to={{
currencyType: "usd",
amount: 419288.98,
shouldBeFormatted: false,
currency: "usd",
size: "lg",
}}
/>
Expand Down
24 changes: 15 additions & 9 deletions dapp/src/components/shared/CurrencyBalance/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import React, { useMemo } from "react"
import { Box, useMultiStyleConfig, TextProps } from "@chakra-ui/react"
import { formatTokenAmount, numberToLocaleString } from "../../../utils"
import { CurrencyType } from "../../../types"
import { CURRENCIES_BY_TYPE } from "../../../constants"
import {
formatTokenAmount,
getCurrencyByType,
isCurrencyType,
numberToLocaleString,
} from "../../../utils"
import { Currency, CurrencyType } from "../../../types"

export type CurrencyBalanceProps = {
currencyType: CurrencyType
currency: Currency | CurrencyType
amount?: string | number
shouldBeFormatted?: boolean
desiredDecimals?: number
Expand All @@ -14,7 +18,7 @@ export type CurrencyBalanceProps = {
} & TextProps

export function CurrencyBalance({
currencyType,
currency,
amount,
shouldBeFormatted = true,
desiredDecimals = 2,
Expand All @@ -24,23 +28,25 @@ export function CurrencyBalance({
}: CurrencyBalanceProps) {
const styles = useMultiStyleConfig("CurrencyBalance", { size, variant })

const currency = CURRENCIES_BY_TYPE[currencyType]
const { symbol, decimals } = isCurrencyType(currency)
? getCurrencyByType(currency)
: currency

const balance = useMemo(() => {
const value = amount ?? 0
if (shouldBeFormatted)
return formatTokenAmount(value, currency.decimals, desiredDecimals)
return formatTokenAmount(value, decimals, desiredDecimals)

return numberToLocaleString(value, desiredDecimals)
}, [amount, currency, desiredDecimals, shouldBeFormatted])
}, [amount, decimals, desiredDecimals, shouldBeFormatted])

return (
<Box>
<Box as="span" __css={styles.balance} {...textProps}>
{balance}
</Box>
<Box as="span" __css={styles.symbol} {...textProps}>
{currency.symbol}
{symbol}
</Box>
</Box>
)
Expand Down
17 changes: 15 additions & 2 deletions dapp/src/components/shared/CurrencyBalanceWithConversion/index.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,30 @@
import React from "react"
import React, { useMemo } from "react"
import { CurrencyBalance, CurrencyBalanceProps } from "../CurrencyBalance"

const MOCK_CONVERSION_AMOUNT = 100

export function CurrencyBalanceWithConversion({
from,
to,
}: {
from: CurrencyBalanceProps
to: CurrencyBalanceProps
}) {
// TODO: Make the correct conversion
const conversionAmount = useMemo(() => {
if (!from.amount || BigInt(from.amount) < 0n) return undefined

return MOCK_CONVERSION_AMOUNT
}, [from.amount])

return (
<>
<CurrencyBalance {...from} />
<CurrencyBalance {...to} />
<CurrencyBalance
amount={conversionAmount}
shouldBeFormatted={false}
{...to}
/>
</>
)
}
4 changes: 4 additions & 0 deletions dapp/src/components/shared/Form/Form.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { chakra } from "@chakra-ui/react"
import { Form as FormikForm } from "formik"

export const Form = chakra(FormikForm)
24 changes: 24 additions & 0 deletions dapp/src/components/shared/Form/FormTokenBalanceInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from "react"
import { useField } from "formik"
import TokenBalanceInput, { TokenBalanceInputProps } from "../TokenBalanceInput"

export type FormTokenBalanceInputProps = {
name: string
} & Omit<TokenBalanceInputProps, "setAmount">
export function FormTokenBalanceInput({
name,
...restProps
}: FormTokenBalanceInputProps) {
const [field, meta, helpers] = useField(name)

return (
<TokenBalanceInput
{...restProps}
{...field}
amount={meta.value}
setAmount={helpers.setValue}
hasError={Boolean(meta.touched && meta.error)}
errorMsgText={meta.error}
/>
)
}
2 changes: 2 additions & 0 deletions dapp/src/components/shared/Form/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./Form"
export * from "./FormTokenBalanceInput"
26 changes: 16 additions & 10 deletions dapp/src/components/shared/ModalBase/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ import {
ModalContent,
ModalOverlay,
} from "@chakra-ui/react"
import { ModalFlowContext, ModalFlowContextValue } from "../../../contexts"
import {
ModalFlowContext,
ModalFlowContextValue,
TransactionContextProvider,
} from "../../../contexts"
import { useSidebar } from "../../../hooks"
import SupportWrapper from "../../Modals/Support"

Expand Down Expand Up @@ -66,14 +70,16 @@ export default function ModalBase({
)

return (
<ModalFlowContext.Provider value={contextValue}>
<Modal size="lg" isOpen={isOpen} onClose={handleClose}>
<ModalOverlay mt="header_height" />
<ModalContent mt="modal_shift">
<ModalCloseButton />
<SupportWrapper>{children}</SupportWrapper>
</ModalContent>
</Modal>
</ModalFlowContext.Provider>
<TransactionContextProvider>
<ModalFlowContext.Provider value={contextValue}>
<Modal size="lg" isOpen={isOpen} onClose={handleClose}>
<ModalOverlay mt="header_height" />
<ModalContent mt="modal_shift">
<ModalCloseButton />
<SupportWrapper>{children}</SupportWrapper>
</ModalContent>
</Modal>
</ModalFlowContext.Provider>
</TransactionContextProvider>
)
}
Loading