@ensofinance/checkout-widget 0.0.12 → 0.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,267 +0,0 @@
1
- import { Box, Icon, Text } from "@chakra-ui/react";
2
- import { HeaderWrapper, HeaderTitle, BodyWrapper } from "../ui/styled";
3
- import { ChevronLeft, X, ArrowDownUpIcon } from "lucide-react";
4
- import { useContext, useState, useEffect, useMemo } from "react";
5
- import { Address } from "viem";
6
- import Modal from "../modal";
7
- import { CheckoutContext } from "../Checkout";
8
- import { Button, IconButton, Tab, Input } from "../ui";
9
- import CurrencySwapDisplay from "../CurrencySwapDisplay";
10
- import { useEnsoPrice, useEnsoToken } from "@/enso-api/api";
11
- import { useAppStore } from "@/store";
12
- import {
13
- normalizeValue,
14
- denormalizeValue,
15
- formatNumber,
16
- formatUSD,
17
- } from "@/util";
18
- import { useTokenBalance } from "@/util/wallet";
19
-
20
- type InputMode = "usd" | "token";
21
-
22
- const percentageOptions = [
23
- { label: "25%", value: 25 },
24
- { label: "50%", value: 50 },
25
- { label: "75%", value: 75 },
26
- { label: "Max", value: 100 },
27
- ];
28
-
29
- const WalletAmountStep = ({ nextStep }: { nextStep?: string }) => {
30
- const { handleClose, setStep } = useContext(CheckoutContext);
31
- const [usdValue, setUsdValue] = useState<string>("10.10");
32
- // const [tokenAmount, setTokenAmount] = useState<string>("");
33
- const [inputMode, setInputMode] = useState<InputMode>("usd");
34
-
35
- const tokenIn = useAppStore((state) => state.tokenIn);
36
- const tokenOut = useAppStore((state) => state.tokenOut);
37
- const chainIdOut = useAppStore((state) => state.chainIdOut);
38
- const chainIdIn = useAppStore((state) => state.chainIdIn);
39
- const setAmountIn = useAppStore((state) => state.setAmountIn);
40
- const amountIn = useAppStore((state) => state.amountIn);
41
- const [initialLoad, setInitialLoad] = useState(true);
42
-
43
- const {
44
- data: [tokenDetails],
45
- } = useEnsoToken(tokenIn, chainIdIn);
46
- const {
47
- data: [tokenOutDetails],
48
- } = useEnsoToken(tokenOut, chainIdOut);
49
- const { data: priceData } = useEnsoPrice(chainIdIn, tokenIn);
50
-
51
- const tokenValue = useMemo(() => {
52
- return normalizeValue(amountIn, tokenDetails?.decimals);
53
- }, [amountIn, tokenDetails?.decimals]);
54
-
55
- const balanceIn = useTokenBalance(tokenIn as Address, chainIdIn);
56
-
57
- // Handle percentage selection
58
- const handlePercentageSelect = (percent: number) => {
59
- if (!balanceIn || !priceData || !tokenDetails?.decimals) {
60
- setUsdValue("0.00");
61
- return;
62
- }
63
-
64
- const amountToSet = (
65
- (BigInt(balanceIn) * BigInt(percent)) /
66
- BigInt(100)
67
- ).toString();
68
-
69
- setAmountIn(amountToSet);
70
- setUsdValue(
71
- (
72
- +normalizeValue(amountToSet, tokenDetails?.decimals) * priceData
73
- ).toFixed(2),
74
- );
75
- };
76
-
77
- useEffect(() => {
78
- if (initialLoad && priceData && tokenDetails && +balanceIn > 0) {
79
- setInitialLoad(false);
80
- handlePercentageSelect(100);
81
- }
82
- }, [balanceIn, initialLoad, priceData, tokenDetails, balanceIn]);
83
-
84
- // Handle input change based on current mode
85
- const handleInputChange = (value: string) => {
86
- if (inputMode === "usd") {
87
- const cleanUsd = value.replace("$", "");
88
- // Clean the input from usd sign
89
- console.log(cleanUsd, priceData, tokenDetails?.decimals);
90
- setUsdValue(cleanUsd);
91
- setAmountIn(
92
- denormalizeValue(
93
- (parseFloat(cleanUsd) / priceData).toString(),
94
- tokenDetails?.decimals,
95
- ),
96
- );
97
- } else {
98
- setAmountIn(denormalizeValue(value, tokenDetails?.decimals));
99
- setUsdValue((parseFloat(value) * priceData).toFixed(2));
100
- }
101
- };
102
-
103
- // Toggle between USD and token input modes
104
- const handleToggleMode = () => {
105
- setInputMode(inputMode === "usd" ? "token" : "usd");
106
- };
107
-
108
- // Get input placeholder and display value
109
- const getInputDisplay = () => {
110
- const formattedValue = formatNumber(tokenValue);
111
- const safeUsdValue = parseFloat(usdValue) > 0 ? usdValue : 0;
112
-
113
- if (inputMode === "usd") {
114
- return {
115
- placeholder: "$10.00",
116
- displayValue: safeUsdValue ? `$${safeUsdValue}` : "",
117
- equivalentValue: tokenValue
118
- ? `${formattedValue} ${tokenDetails?.symbol}`
119
- : "—",
120
- };
121
- }
122
-
123
- return {
124
- placeholder: "0.00",
125
- displayValue: formattedValue,
126
- equivalentValue: formatUSD(safeUsdValue),
127
- };
128
- };
129
-
130
- const { placeholder, displayValue, equivalentValue } = getInputDisplay();
131
- const notEnoughBalance = +balanceIn < +amountIn;
132
-
133
- return (
134
- <>
135
- <Modal.Header>
136
- <HeaderWrapper>
137
- <IconButton
138
- minWidth={"16px"}
139
- minHeight={"16px"}
140
- maxWidth={"16px"}
141
- onClick={() => setStep("selectToken")}
142
- >
143
- <Icon
144
- as={ChevronLeft}
145
- color="gray"
146
- width={"16px"}
147
- height={"16px"}
148
- />
149
- </IconButton>
150
-
151
- <Box display="flex" flexDirection="column" gap={"4px"}>
152
- <HeaderTitle>Deposit</HeaderTitle>
153
- </Box>
154
-
155
- {handleClose && (
156
- <IconButton
157
- onClick={handleClose}
158
- width={"40px"}
159
- marginLeft={"auto"}
160
- >
161
- <Icon
162
- as={X}
163
- color="gray"
164
- width={"16px"}
165
- height={"16px"}
166
- />
167
- </IconButton>
168
- )}
169
- </HeaderWrapper>
170
- </Modal.Header>
171
-
172
- <Modal.Body>
173
- <BodyWrapper>
174
- <Box display={"flex"} flexDirection={"column"} gap={"8px"}>
175
- <Box
176
- display={"flex"}
177
- flexDirection={"column"}
178
- gap={"8px"}
179
- alignItems={"center"}
180
- padding={"25.5px"}
181
- >
182
- {/* Main Input */}
183
- <Input
184
- inputMode="decimal"
185
- marginY={"8px"}
186
- variant={"text"}
187
- placeholder={placeholder}
188
- value={displayValue}
189
- onChange={(e) =>
190
- handleInputChange(e.target.value)
191
- }
192
- />
193
-
194
- {/* Toggle Button and Equivalent Display */}
195
- <Box
196
- display={"flex"}
197
- gap={"3"}
198
- alignItems={"center"}
199
- onClick={handleToggleMode}
200
- _hover={{ background: "bg.subtle" }}
201
- cursor={"pointer"}
202
- borderRadius={"lg"}
203
- px={"3"}
204
- >
205
- <IconButton
206
- minWidth={"24px"}
207
- minHeight={"24px"}
208
- maxWidth={"24px"}
209
- background={"transparent"}
210
- >
211
- <Icon
212
- as={ArrowDownUpIcon}
213
- color="gray"
214
- width={"16px"}
215
- height={"16px"}
216
- />
217
- </IconButton>
218
-
219
- {/* Small equivalent value display */}
220
- <Text fontSize="sm" color="fg.muted">
221
- {equivalentValue}
222
- </Text>
223
- </Box>
224
- </Box>
225
- <Box
226
- display={"flex"}
227
- gap={"4px"}
228
- justifyContent={"center"}
229
- paddingBottom={"35px"}
230
- >
231
- {percentageOptions.map((option) => (
232
- <Tab
233
- key={option.label}
234
- onClick={() =>
235
- handlePercentageSelect(option.value)
236
- }
237
- >
238
- {option.label}
239
- </Tab>
240
- ))}
241
- </Box>
242
- </Box>
243
-
244
- <CurrencySwapDisplay
245
- tokenOut={tokenOutDetails}
246
- tokenIn={tokenDetails}
247
- chainIdIn={chainIdIn}
248
- chainIdOut={chainIdOut}
249
- />
250
-
251
- <Button
252
- onClick={() =>
253
- notEnoughBalance
254
- ? undefined
255
- : setStep(nextStep ?? "quote")
256
- }
257
- disabled={notEnoughBalance}
258
- >
259
- Continue
260
- </Button>
261
- </BodyWrapper>
262
- </Modal.Body>
263
- </>
264
- );
265
- };
266
-
267
- export default WalletAmountStep;
@@ -1,128 +0,0 @@
1
- import { Box, Icon, Skeleton } from "@chakra-ui/react";
2
- import {
3
- HeaderWrapper,
4
- HeaderTitle,
5
- HeaderDescription,
6
- ListWrapper,
7
- BodyWrapper,
8
- } from "../ui/styled";
9
- import { ChevronLeft, X } from "lucide-react";
10
- import { useContext, useEffect } from "react";
11
- import Modal from "../modal";
12
- import { CheckoutContext } from "../Checkout";
13
- import { Button, IconButton } from "../ui";
14
- import { AssetCard } from "../cards";
15
- import { useAppStore } from "@/store";
16
- import { useWalletBalance } from "@/enso-api/api";
17
- import { formatNumber, formatUSD, normalizeValue } from "@/util";
18
-
19
- const SelectTokenStep = () => {
20
- const { handleClose, setFlow, setStep } = useContext(CheckoutContext);
21
- const setIsCheckout = useAppStore((state) => state.setIsCheckout);
22
- const setTokenIn = useAppStore((state) => state.setTokenIn);
23
- const tokenIn = useAppStore((state) => state.tokenIn);
24
- const setChainIdIn = useAppStore((state) => state.setChainIdIn);
25
- const chainIdIn = useAppStore((state) => state.chainIdIn);
26
- const { holdingsList, total, isLoading } = useWalletBalance();
27
-
28
- useEffect(() => {
29
- setIsCheckout(false);
30
- }, []);
31
-
32
- return (
33
- <>
34
- <Modal.Header>
35
- <HeaderWrapper>
36
- <IconButton
37
- minWidth={"16px"}
38
- minHeight={"16px"}
39
- maxWidth={"16px"}
40
- onClick={() => {
41
- setFlow("");
42
- setStep("");
43
- }}
44
- >
45
- <Icon
46
- as={ChevronLeft}
47
- color="gray"
48
- width={"16px"}
49
- height={"16px"}
50
- />
51
- </IconButton>
52
- <Box display="flex" flexDirection="column" gap={"4px"}>
53
- <HeaderTitle>Deposit</HeaderTitle>
54
- <HeaderDescription>
55
- Balance: {formatUSD(total)}
56
- </HeaderDescription>
57
- </Box>
58
- {handleClose && (
59
- <IconButton
60
- onClick={handleClose}
61
- width={"40px"}
62
- marginLeft={"auto"}
63
- >
64
- <Icon
65
- as={X}
66
- color="gray"
67
- width={"16px"}
68
- height={"16px"}
69
- />
70
- </IconButton>
71
- )}
72
- </HeaderWrapper>
73
- </Modal.Header>
74
-
75
- <Modal.Body>
76
- <BodyWrapper>
77
- <Box overflowY={"scroll"} maxH={"400px"}>
78
- <ListWrapper>
79
- {isLoading
80
- ? Array.from({ length: 10 }).map((_, index) => (
81
- <Skeleton
82
- key={index}
83
- height="40px"
84
- width="300px"
85
- />
86
- ))
87
- : holdingsList?.map((asset) => (
88
- <AssetCard
89
- key={`${asset.token}-${asset.chainId}`}
90
- chainId={asset.chainId}
91
- icon={asset.logoUri}
92
- title={asset.name}
93
- balance={`${formatNumber(
94
- normalizeValue(
95
- asset.amount,
96
- asset.decimals,
97
- ),
98
- )} ${asset.symbol}`}
99
- usdBalance={formatUSD(asset.total)}
100
- tag={""}
101
- loading={false}
102
- selected={
103
- asset.token === tokenIn &&
104
- asset.chainId === chainIdIn
105
- }
106
- onClick={() => {
107
- setTokenIn(asset.token);
108
- setChainIdIn(asset.chainId);
109
- }}
110
- />
111
- ))}
112
- </ListWrapper>
113
- </Box>
114
- <Button
115
- onClick={() => {
116
- setStep("selectAmount");
117
- }}
118
- disabled={!tokenIn}
119
- >
120
- Continue
121
- </Button>
122
- </BodyWrapper>
123
- </Modal.Body>
124
- </>
125
- );
126
- };
127
-
128
- export default SelectTokenStep;