@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.
- package/dist/checkout-widget.es.js +25627 -24338
- package/dist/checkout-widget.es.js.map +1 -1
- package/dist/checkout-widget.umd.js +64 -59
- package/dist/checkout-widget.umd.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/package.json +1 -1
- package/src/assets/providers/alchemypay.svg +21 -0
- package/src/assets/providers/banxa.svg +21 -0
- package/src/assets/providers/binanceconnect.svg +14 -0
- package/src/assets/providers/kryptonim.svg +6 -0
- package/src/assets/providers/mercuryo.svg +21 -0
- package/src/assets/providers/moonpay.svg +14 -0
- package/src/assets/providers/stripe.svg +16 -0
- package/src/assets/providers/swapped.svg +1 -0
- package/src/assets/providers/topper.svg +14 -0
- package/src/assets/providers/transak.svg +21 -0
- package/src/assets/providers/unlimit.svg +21 -0
- package/src/components/AmountInput.tsx +41 -25
- package/src/components/ChakraProvider.tsx +36 -13
- package/src/components/Checkout.tsx +7 -1
- package/src/components/CurrencySwapDisplay.tsx +59 -22
- package/src/components/DepositProcessing.tsx +1 -1
- package/src/components/ExchangeConfirmSecurity.tsx +1 -1
- package/src/components/QuoteParameters.tsx +1 -1
- package/src/components/TransactionDetailRow.tsx +2 -2
- package/src/components/cards/ExchangeCard.tsx +1 -1
- package/src/components/cards/OptionCard.tsx +2 -1
- package/src/components/cards/WalletCard.tsx +1 -1
- package/src/components/modal.tsx +3 -3
- package/src/components/steps/CardBuyFlow/CardBuyFlow.tsx +412 -0
- package/src/components/steps/CardBuyFlow/ChooseAmountStep.tsx +352 -0
- package/src/components/steps/CardBuyFlow/OpenWidgetStep.tsx +193 -0
- package/src/components/steps/ExchangeFlow.tsx +231 -1404
- package/src/components/steps/FlowSelector.tsx +117 -60
- package/src/components/steps/SmartAccountFlow.tsx +372 -0
- package/src/components/steps/WalletFlow/WalletAmountStep.tsx +2 -2
- package/src/components/steps/WalletFlow/WalletConfirmStep.tsx +92 -51
- package/src/components/steps/WalletFlow/WalletFlow.tsx +17 -16
- package/src/components/steps/WalletFlow/WalletQuoteStep.tsx +2 -2
- package/src/components/steps/WalletFlow/WalletTokenStep.tsx +6 -4
- package/src/components/steps/shared/ChooseAmountStep.tsx +325 -0
- package/src/components/steps/shared/SignUserOpStep.tsx +117 -0
- package/src/components/steps/shared/TrackUserOpStep.tsx +625 -0
- package/src/components/steps/shared/exchangeIntegration.ts +19 -0
- package/src/components/steps/shared/types.ts +22 -0
- package/src/components/ui/index.tsx +23 -6
- package/src/components/ui/toaster.tsx +2 -1
- package/src/components/ui/transitions.tsx +16 -0
- package/src/enso-api/model/bridgeTransactionResponse.ts +37 -0
- package/src/enso-api/model/bridgeTransactionResponseStatus.ts +25 -0
- package/src/enso-api/model/ensoEvent.ts +30 -0
- package/src/enso-api/model/ensoMetadata.ts +23 -0
- package/src/enso-api/model/layerZeroControllerCheckBridgeTransactionParams.ts +21 -0
- package/src/enso-api/model/layerZeroMessageStatus.ts +39 -0
- package/src/enso-api/model/refundDetails.ts +21 -0
- package/src/types/index.ts +99 -0
- package/src/util/constants.tsx +27 -0
- package/src/util/enso-hooks.tsx +75 -61
- package/src/util/meld-hooks.tsx +533 -0
- package/src/assets/usdc.webp +0 -0
- 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 = "
|
|
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:
|
|
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 [
|
|
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
|
|
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
|
-
|
|
96
|
-
|
|
97
|
-
|
|
107
|
+
const receipt = callsStatus.data.receipts?.[0];
|
|
108
|
+
const hash = receipt?.transactionHash;
|
|
109
|
+
|
|
110
|
+
if (hash) {
|
|
98
111
|
setTrackingHash(hash);
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
: "
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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,
|
|
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
|
-
|
|
124
|
-
|
|
125
|
-
sendTxns(
|
|
126
|
-
setCalled(true);
|
|
174
|
+
if (!calledRef.current && ready) {
|
|
175
|
+
calledRef.current = true;
|
|
176
|
+
sendTxns({ onStep, onFail });
|
|
127
177
|
}
|
|
128
|
-
}, [
|
|
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(
|
|
186
|
+
setStep(0);
|
|
137
187
|
};
|
|
138
188
|
|
|
139
189
|
const handleRetry = () => {
|
|
140
|
-
|
|
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 "
|
|
205
|
+
return "success";
|
|
171
206
|
case "failed":
|
|
172
|
-
return "
|
|
207
|
+
return "error";
|
|
173
208
|
default:
|
|
174
|
-
return "
|
|
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
|
|
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
|
|
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
|
|
15
|
-
SelectAmount
|
|
16
|
-
Quote
|
|
17
|
-
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={
|
|
50
|
+
return <WalletTokenStep setStep={setCurrentStep} />;
|
|
54
51
|
case WalletFlowStep.SelectAmount:
|
|
55
|
-
return <WalletAmountStep setStep={
|
|
52
|
+
return <WalletAmountStep setStep={setCurrentStep} />;
|
|
56
53
|
case WalletFlowStep.Quote:
|
|
57
|
-
return <WalletQuoteStep setStep={
|
|
54
|
+
return <WalletQuoteStep setStep={setCurrentStep} />;
|
|
58
55
|
case WalletFlowStep.ConfirmTransfer:
|
|
59
|
-
return <WalletConfirmStep setStep={
|
|
56
|
+
return <WalletConfirmStep setStep={setCurrentStep} />;
|
|
60
57
|
default:
|
|
61
|
-
return <WalletTokenStep setStep={
|
|
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="
|
|
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="
|
|
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>
|
|
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:
|
|
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(
|
|
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:
|
|
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
|
-
!(
|
|
25
|
-
|
|
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(
|
|
75
|
+
setStep(1);
|
|
74
76
|
}}
|
|
75
77
|
disabled={!tokenIn}
|
|
76
78
|
>
|