@ensofinance/checkout-widget 0.1.7 → 0.1.8

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.
Files changed (61) hide show
  1. package/dist/checkout-widget.es.js +25627 -24338
  2. package/dist/checkout-widget.es.js.map +1 -1
  3. package/dist/checkout-widget.umd.js +64 -59
  4. package/dist/checkout-widget.umd.js.map +1 -1
  5. package/dist/index.d.ts +5 -1
  6. package/package.json +1 -1
  7. package/src/assets/providers/alchemypay.svg +21 -0
  8. package/src/assets/providers/banxa.svg +21 -0
  9. package/src/assets/providers/binanceconnect.svg +14 -0
  10. package/src/assets/providers/kryptonim.svg +6 -0
  11. package/src/assets/providers/mercuryo.svg +21 -0
  12. package/src/assets/providers/moonpay.svg +14 -0
  13. package/src/assets/providers/stripe.svg +16 -0
  14. package/src/assets/providers/swapped.svg +1 -0
  15. package/src/assets/providers/topper.svg +14 -0
  16. package/src/assets/providers/transak.svg +21 -0
  17. package/src/assets/providers/unlimit.svg +21 -0
  18. package/src/components/AmountInput.tsx +41 -25
  19. package/src/components/ChakraProvider.tsx +36 -13
  20. package/src/components/Checkout.tsx +7 -1
  21. package/src/components/CurrencySwapDisplay.tsx +59 -22
  22. package/src/components/DepositProcessing.tsx +1 -1
  23. package/src/components/ExchangeConfirmSecurity.tsx +1 -1
  24. package/src/components/QuoteParameters.tsx +1 -1
  25. package/src/components/TransactionDetailRow.tsx +2 -2
  26. package/src/components/cards/ExchangeCard.tsx +1 -1
  27. package/src/components/cards/OptionCard.tsx +2 -1
  28. package/src/components/cards/WalletCard.tsx +1 -1
  29. package/src/components/modal.tsx +3 -3
  30. package/src/components/steps/CardBuyFlow/CardBuyFlow.tsx +412 -0
  31. package/src/components/steps/CardBuyFlow/ChooseAmountStep.tsx +352 -0
  32. package/src/components/steps/CardBuyFlow/OpenWidgetStep.tsx +193 -0
  33. package/src/components/steps/ExchangeFlow.tsx +231 -1404
  34. package/src/components/steps/FlowSelector.tsx +117 -60
  35. package/src/components/steps/SmartAccountFlow.tsx +372 -0
  36. package/src/components/steps/WalletFlow/WalletAmountStep.tsx +2 -2
  37. package/src/components/steps/WalletFlow/WalletConfirmStep.tsx +92 -51
  38. package/src/components/steps/WalletFlow/WalletFlow.tsx +17 -16
  39. package/src/components/steps/WalletFlow/WalletQuoteStep.tsx +2 -2
  40. package/src/components/steps/WalletFlow/WalletTokenStep.tsx +6 -4
  41. package/src/components/steps/shared/ChooseAmountStep.tsx +325 -0
  42. package/src/components/steps/shared/SignUserOpStep.tsx +117 -0
  43. package/src/components/steps/shared/TrackUserOpStep.tsx +625 -0
  44. package/src/components/steps/shared/exchangeIntegration.ts +19 -0
  45. package/src/components/steps/shared/types.ts +22 -0
  46. package/src/components/ui/index.tsx +23 -6
  47. package/src/components/ui/toaster.tsx +2 -1
  48. package/src/components/ui/transitions.tsx +16 -0
  49. package/src/enso-api/model/bridgeTransactionResponse.ts +37 -0
  50. package/src/enso-api/model/bridgeTransactionResponseStatus.ts +25 -0
  51. package/src/enso-api/model/ensoEvent.ts +30 -0
  52. package/src/enso-api/model/ensoMetadata.ts +23 -0
  53. package/src/enso-api/model/layerZeroControllerCheckBridgeTransactionParams.ts +21 -0
  54. package/src/enso-api/model/layerZeroMessageStatus.ts +39 -0
  55. package/src/enso-api/model/refundDetails.ts +21 -0
  56. package/src/types/index.ts +99 -0
  57. package/src/util/constants.tsx +27 -0
  58. package/src/util/enso-hooks.tsx +75 -61
  59. package/src/util/meld-hooks.tsx +533 -0
  60. package/src/assets/usdc.webp +0 -0
  61. package/src/assets/usdt.webp +0 -0
@@ -1,13 +1,14 @@
1
1
  import { Box, Table, Text, Image } from "@chakra-ui/react";
2
- import { useEffect, useState, useMemo, useCallback } from "react";
2
+ import { useEffect, useState, useMemo, useCallback, useRef } from "react";
3
3
  import { useAccount } from "wagmi";
4
+ import { useCallsStatus } from "wagmi/experimental";
4
5
  import { Address } from "viem";
5
6
  import { BodyWrapper } from "@/components/ui/styled";
6
7
  import { Button } from "@/components/ui";
7
8
  import { CircleTimer } from "@/components/CircleTimer";
8
9
  import { TransactionDetailRow } from "@/components/TransactionDetailRow";
9
10
  import DepositProcessing from "@/components/DepositProcessing";
10
- import { useSendTxns, useRouteData, useAppDetails } from "@/util/enso-hooks";
11
+ import { useSendTxns, useRouteData, useAppDetails, type TxStep } from "@/util/enso-hooks";
11
12
  import { compareCaseInsensitive, getChainIcon } from "@/util";
12
13
  import { getChainEtherscanUrl } from "@/util/common";
13
14
  import { useTrackTx, useTxByHash } from "@/util/tx-tracker";
@@ -19,7 +20,7 @@ import { ETH_ADDRESS } from "@/util/constants";
19
20
  import SuccessIcon from "@/assets/success.svg";
20
21
  import FailIcon from "@/assets/fail.svg";
21
22
 
22
- type TransferStatus = "processing" | "success" | "failed" | "idle";
23
+ type TransferStatus = "idle" | "approving" | "executing" | "processing" | "success" | "failed";
23
24
 
24
25
  const useOperationsCalls = () => {
25
26
  const { chainIdIn, tokenIn, amountIn } = useAppDetails();
@@ -70,16 +71,18 @@ const useOperationsCalls = () => {
70
71
  const WalletConfirmStep = ({
71
72
  setStep,
72
73
  }: {
73
- setStep: (step: string) => void;
74
+ setStep: (step: number) => void;
74
75
  }) => {
75
76
  const [status, setStatus] = useState<TransferStatus>("idle");
76
77
  const [isTimerFinished, setIsTimerFinished] = useState(false);
77
78
  const { address } = useAccount();
78
79
  const [trackingHash, setTrackingHash] = useState("");
79
- const [called, setCalled] = useState(false);
80
+ const [bundleId, setBundleId] = useState<string>();
81
+ const calledRef = useRef(false);
80
82
 
81
83
  const { chainIdIn, chainIdOut } = useAppDetails();
82
84
  const { calls } = useOperationsCalls();
85
+ const isCrosschain = chainIdIn !== chainIdOut;
83
86
 
84
87
  const { sendTxns, ready } = useSendTxns({
85
88
  calls,
@@ -87,30 +90,78 @@ const WalletConfirmStep = ({
87
90
  chainId: chainIdIn,
88
91
  });
89
92
 
90
- // const [trackingHash, setTrackingHash] = useState("");
91
93
  const { track } = useTrackTx();
92
94
 
93
- const isCrosschain = chainIdIn !== chainIdOut;
95
+ const callsStatus = useCallsStatus({
96
+ id: bundleId as string,
97
+ query: {
98
+ enabled: !!bundleId,
99
+ refetchInterval: (query) =>
100
+ query.state.data?.status === "success" ? false : 2000,
101
+ },
102
+ });
103
+
104
+ useEffect(() => {
105
+ if (!callsStatus.data || callsStatus.data.status !== "success") return;
94
106
 
95
- const onTxSend = useCallback(
96
- (hash: string) => {
97
- setStatus("processing");
107
+ const receipt = callsStatus.data.receipts?.[0];
108
+ const hash = receipt?.transactionHash;
109
+
110
+ if (hash) {
98
111
  setTrackingHash(hash);
99
- track({
100
- hash: hash as `0x${string}`,
101
- isActive: true,
102
- chainId: chainIdIn,
103
- crosschain: isCrosschain,
104
- status: isCrosschain
105
- ? "(0/4) Waiting for source transaction completion"
106
- : "Transaction in progess",
107
- message: "Transaction confirmed",
108
- onConfirmed: () => {
109
- setStatus("success");
110
- },
111
- });
112
+
113
+ if (isCrosschain) {
114
+ track({
115
+ hash: hash as `0x${string}`,
116
+ isActive: true,
117
+ chainId: chainIdIn,
118
+ crosschain: true,
119
+ status: "(0/4) Waiting for source transaction completion",
120
+ message: "Transaction confirmed",
121
+ onConfirmed: () => {
122
+ setStatus("success");
123
+ },
124
+ });
125
+ return;
126
+ }
127
+ }
128
+ setStatus("success");
129
+ }, [callsStatus.data, isCrosschain, chainIdIn, track]);
130
+
131
+ const onStep = useCallback(
132
+ (step: TxStep) => {
133
+ switch (step.type) {
134
+ case "approving":
135
+ setStatus("approving");
136
+ break;
137
+ case "executing":
138
+ setStatus("executing");
139
+ break;
140
+ case "confirmed": {
141
+ setStatus("processing");
142
+ setTrackingHash(step.hash);
143
+ track({
144
+ hash: step.hash as `0x${string}`,
145
+ isActive: true,
146
+ chainId: chainIdIn,
147
+ crosschain: isCrosschain,
148
+ status: isCrosschain
149
+ ? "(0/4) Waiting for source transaction completion"
150
+ : "Transaction in progress",
151
+ message: "Transaction confirmed",
152
+ onConfirmed: () => {
153
+ setStatus("success");
154
+ },
155
+ });
156
+ break;
157
+ }
158
+ case "atomic":
159
+ setBundleId(step.bundleId);
160
+ setStatus("processing");
161
+ break;
162
+ }
112
163
  },
113
- [chainIdIn, chainIdOut],
164
+ [chainIdIn, isCrosschain, track],
114
165
  );
115
166
 
116
167
  const onFail = useCallback((error: any) => {
@@ -120,12 +171,11 @@ const WalletConfirmStep = ({
120
171
 
121
172
  // Initiate the transaction when wallet is ready
122
173
  useEffect(() => {
123
- console.log(called, ready);
124
- if (!called && ready) {
125
- sendTxns(onTxSend, onFail);
126
- setCalled(true);
174
+ if (!calledRef.current && ready) {
175
+ calledRef.current = true;
176
+ sendTxns({ onStep, onFail });
127
177
  }
128
- }, [called, ready, sendTxns, onTxSend]);
178
+ }, [ready, sendTxns, onStep, onFail]);
129
179
 
130
180
  const handleTimerFinish = () => {
131
181
  setIsTimerFinished(true);
@@ -133,14 +183,11 @@ const WalletConfirmStep = ({
133
183
 
134
184
  const handleNewDeposit = () => {
135
185
  // Reset to initial step or handle new deposit logic
136
- setStep("selectToken");
186
+ setStep(0);
137
187
  };
138
188
 
139
189
  const handleRetry = () => {
140
- // Reset to previous step to retry the transfer
141
- // setStatus("processing");
142
- // setIsTimerFinished(false);
143
- setStep("quote");
190
+ setStep(2);
144
191
  };
145
192
 
146
193
  const tx = useTxByHash(trackingHash);
@@ -152,26 +199,14 @@ const WalletConfirmStep = ({
152
199
  chainId: chainIdIn,
153
200
  });
154
201
 
155
- // useEffect(() => {
156
- // if (status === "processing") {
157
- // // Simulate transfer processing - randomly succeed or fail after timer
158
- // const timer = setTimeout(() => {
159
- // const shouldSucceed = Math.random() > 0.3; // 70% success rate for demo
160
- // setStatus(shouldSucceed ? "success" : "failed");
161
- // }, 2500); // 2.5 seconds processing time
162
-
163
- // return () => clearTimeout(timer);
164
- // }
165
- // }, [status]);
166
-
167
202
  const getStatusColor = () => {
168
203
  switch (status) {
169
204
  case "success":
170
- return "#14AE5C";
205
+ return "success";
171
206
  case "failed":
172
- return "#E84142";
207
+ return "error";
173
208
  default:
174
- return "#1E171F";
209
+ return "fg";
175
210
  }
176
211
  };
177
212
 
@@ -181,6 +216,10 @@ const WalletConfirmStep = ({
181
216
  return "Success";
182
217
  case "failed":
183
218
  return "Failed";
219
+ case "approving":
220
+ return "Approving token access...";
221
+ case "executing":
222
+ return "Confirm transaction in wallet";
184
223
  case "idle":
185
224
  return "Awaiting wallet approval";
186
225
  default:
@@ -192,6 +231,8 @@ const WalletConfirmStep = ({
192
231
  switch (status) {
193
232
  case "processing":
194
233
  case "idle":
234
+ case "approving":
235
+ case "executing":
195
236
  return (
196
237
  <CircleTimer
197
238
  start={status === "processing"}
@@ -208,7 +249,7 @@ const WalletConfirmStep = ({
208
249
  >
209
250
  <Image
210
251
  src={SuccessIcon}
211
- boxShadow="0px 0px 20px #14AE5C"
252
+ boxShadow="0px 0px 20px var(--chakra-colors-success)"
212
253
  borderRadius="90%"
213
254
  width="58px"
214
255
  height="58px"
@@ -225,7 +266,7 @@ const WalletConfirmStep = ({
225
266
  >
226
267
  <Image
227
268
  src={FailIcon}
228
- boxShadow="0px 0px 20px #E84142"
269
+ boxShadow="0px 0px 20px var(--chakra-colors-error)"
229
270
  borderRadius="90%"
230
271
  width="58px"
231
272
  height="58px"
@@ -9,12 +9,13 @@ import { CheckoutContext } from "@/components/Checkout";
9
9
  import Modal from "@/components/modal";
10
10
  import { IconButton } from "@/components/ui";
11
11
  import { HeaderWrapper, HeaderTitle } from "@/components/ui/styled";
12
+ import { AnimatedStep } from "@/components/ui/transitions";
12
13
 
13
14
  export enum WalletFlowStep {
14
- SelectToken = "selectToken",
15
- SelectAmount = "selectAmount",
16
- Quote = "quote",
17
- ConfirmTransfer = "confirmTransfer",
15
+ SelectToken,
16
+ SelectAmount,
17
+ Quote,
18
+ ConfirmTransfer,
18
19
  }
19
20
 
20
21
  const walletSteps = [
@@ -34,10 +35,6 @@ const WalletFlow = ({
34
35
  const [currentStep, setCurrentStep] = useState<WalletFlowStep>(initialStep);
35
36
  const { handleClose, enforceFlow } = useContext(CheckoutContext);
36
37
 
37
- const handleSetStep = (step: WalletFlowStep | string) => {
38
- setCurrentStep(step as WalletFlowStep);
39
- };
40
-
41
38
  const handleBackClick = () => {
42
39
  const index = walletSteps.findIndex((step) => step === currentStep) - 1;
43
40
  if (index >= 0) {
@@ -50,15 +47,15 @@ const WalletFlow = ({
50
47
  const currentStepComponent = (() => {
51
48
  switch (currentStep) {
52
49
  case WalletFlowStep.SelectToken:
53
- return <WalletTokenStep setStep={handleSetStep} />;
50
+ return <WalletTokenStep setStep={setCurrentStep} />;
54
51
  case WalletFlowStep.SelectAmount:
55
- return <WalletAmountStep setStep={handleSetStep} />;
52
+ return <WalletAmountStep setStep={setCurrentStep} />;
56
53
  case WalletFlowStep.Quote:
57
- return <WalletQuoteStep setStep={handleSetStep} />;
54
+ return <WalletQuoteStep setStep={setCurrentStep} />;
58
55
  case WalletFlowStep.ConfirmTransfer:
59
- return <WalletConfirmStep setStep={handleSetStep} />;
56
+ return <WalletConfirmStep setStep={setCurrentStep} />;
60
57
  default:
61
- return <WalletTokenStep setStep={handleSetStep} />;
58
+ return <WalletTokenStep setStep={setCurrentStep} />;
62
59
  }
63
60
  })();
64
61
 
@@ -78,7 +75,7 @@ const WalletFlow = ({
78
75
  >
79
76
  <Icon
80
77
  as={ChevronLeft}
81
- color="gray"
78
+ color="fg.muted"
82
79
  width={"16px"}
83
80
  height={"16px"}
84
81
  />
@@ -105,7 +102,7 @@ const WalletFlow = ({
105
102
  >
106
103
  <Icon
107
104
  as={X}
108
- color="gray"
105
+ color="fg.muted"
109
106
  width={"16px"}
110
107
  height={"16px"}
111
108
  />
@@ -113,7 +110,11 @@ const WalletFlow = ({
113
110
  )}
114
111
  </HeaderWrapper>
115
112
  </Modal.Header>
116
- <Modal.Body>{currentStepComponent}</Modal.Body>
113
+ <Modal.Body>
114
+ <AnimatedStep key={currentStep}>
115
+ {currentStepComponent}
116
+ </AnimatedStep>
117
+ </Modal.Body>
117
118
  </>
118
119
  );
119
120
  };
@@ -7,7 +7,7 @@ import { useAppDetails, useRouteData } from "@/util/enso-hooks";
7
7
  import { useChainName } from "@/util/common";
8
8
  import QuoteParameters from "@/components/QuoteParameters";
9
9
 
10
- const WalletQuoteStep = ({ setStep }: { setStep: (step: string) => void }) => {
10
+ const WalletQuoteStep = ({ setStep }: { setStep: (step: number) => void }) => {
11
11
  const { chainIdIn } = useAppDetails();
12
12
 
13
13
  const { routeLoading, usdAmountIn, routeData } = useRouteData();
@@ -58,7 +58,7 @@ const WalletQuoteStep = ({ setStep }: { setStep: (step: string) => void }) => {
58
58
  onClick={
59
59
  !routeLoading
60
60
  ? () => {
61
- setStep("confirmTransfer");
61
+ setStep(3);
62
62
  }
63
63
  : () => {}
64
64
  }
@@ -7,7 +7,7 @@ import { useAppStore } from "@/store";
7
7
  import { useWalletBalance } from "@/enso-api/api";
8
8
  import { formatNumber, formatUSD, normalizeValue } from "@/util";
9
9
 
10
- const WalletAssetStep = ({ setStep }: { setStep: (step: string) => void }) => {
10
+ const WalletAssetStep = ({ setStep }: { setStep: (step: number) => void }) => {
11
11
  const setSelectedIntegration = useAppStore(
12
12
  (state) => state.setSelectedIntegration,
13
13
  );
@@ -21,8 +21,10 @@ const WalletAssetStep = ({ setStep }: { setStep: (step: string) => void }) => {
21
21
 
22
22
  const filteredHoldings = holdingsList?.filter(
23
23
  (asset) =>
24
- !(asset.token.toLowerCase() === tokenOut.toLowerCase() &&
25
- asset.chainId === chainIdOut),
24
+ !(
25
+ asset.token.toLowerCase() === tokenOut.toLowerCase() &&
26
+ asset.chainId === chainIdOut
27
+ ),
26
28
  );
27
29
 
28
30
  useEffect(() => {
@@ -70,7 +72,7 @@ const WalletAssetStep = ({ setStep }: { setStep: (step: string) => void }) => {
70
72
  </Box>
71
73
  <Button
72
74
  onClick={() => {
73
- setStep("selectAmount");
75
+ setStep(1);
74
76
  }}
75
77
  disabled={!tokenIn}
76
78
  >