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 all 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.

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

function Details({ currency }: { currency: CurrencyType }) {
const value = useTokenAmountFormValue()
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
40 changes: 40 additions & 0 deletions dapp/src/components/Modals/Staking/StakeForm/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React, { useCallback } from "react"
import { Button } from "@chakra-ui/react"
import { 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"

function StakeForm({ goNext }: ModalStep) {
const { btcAccount } = useWalletContext()
const { setTokenAmount } = useTransactionContext()

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

setTokenAmount({ amount: values.amount, currency: "bitcoin" })
goNext()
},
[goNext, setTokenAmount],
)

return (
<TokenAmountForm
tokenBalanceInputPlaceholder="BTC"
currency="bitcoin"
tokenBalance={btcAccount?.balance.toString() ?? "0"}
minTokenAmount={BITCOIN_MIN_AMOUNT}
onSubmitForm={handleSubmitForm}
>
<Details currency="bitcoin" />
<Button type="submit" size="lg" width="100%" mt={4}>
Stake
</Button>
</TokenAmountForm>
)
}

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
14 changes: 7 additions & 7 deletions dapp/src/components/Modals/Support/MissingAccount.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,29 @@ 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
currency: CurrencyType
icon: typeof Icon
requestAccount: (...params: RequestAccountParams) => Promise<void>
}

export default function MissingAccount({
currencyType,
currency,
icon,
requestAccount,
}: MissingAccountProps) {
const currency = CURRENCIES_BY_TYPE[currencyType]
const { name, symbol } = getCurrencyByType(currency)

return (
<>
<ModalHeader>{currency.name} account not installed</ModalHeader>
<ModalHeader>{name} account not installed</ModalHeader>
<ModalBody>
<Icon as={icon} boxSize={32} my={2} />
<TextMd>
{currency.name} account is required to make transactions for
depositing and staking your {currency.symbol}.
{name} account is required to make transactions for depositing and
staking your {symbol}.
</TextMd>
<Alert>
<TextMd>
Expand Down
4 changes: 2 additions & 2 deletions dapp/src/components/Modals/Support/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default function SupportWrapper({
if (!btcAccount)
return (
<MissingAccount
currencyType="bitcoin"
currency="bitcoin"
icon={ConnectBTCAccount}
requestAccount={requestBitcoinAccount}
/>
Expand All @@ -28,7 +28,7 @@ export default function SupportWrapper({
if (!ethAccount)
return (
<MissingAccount
currencyType="ethereum"
currency="ethereum"
icon={ConnectETHAccount}
requestAccount={requestEthereumAccount}
/>
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
19 changes: 11 additions & 8 deletions dapp/src/components/shared/CurrencyBalance/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import React, { useMemo } from "react"
import { Box, useMultiStyleConfig, TextProps } from "@chakra-ui/react"
import { formatTokenAmount, numberToLocaleString } from "../../../utils"
import {
formatTokenAmount,
getCurrencyByType,
numberToLocaleString,
} from "../../../utils"
import { CurrencyType } from "../../../types"
import { CURRENCIES_BY_TYPE } from "../../../constants"

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

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

const currency = CURRENCIES_BY_TYPE[currencyType]
const { symbol, decimals } = getCurrencyByType(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"
Loading