@hot-labs/kit 1.1.0-beta.3 → 1.1.0-beta.5
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/build/OmniConnector.d.ts +1 -0
- package/build/OmniConnector.js.map +1 -1
- package/build/core/Intents.d.ts +21 -6
- package/build/core/Intents.js +81 -46
- package/build/core/Intents.js.map +1 -1
- package/build/core/api.d.ts +16 -1
- package/build/core/api.js +14 -4
- package/build/core/api.js.map +1 -1
- package/build/cosmos/connector.d.ts +2 -2
- package/build/cosmos/connector.js +15 -19
- package/build/cosmos/connector.js.map +1 -1
- package/build/cosmos/wallet.js.map +1 -1
- package/build/exchange.js +1 -5
- package/build/exchange.js.map +1 -1
- package/build/solana/wallet.js +1 -1
- package/build/solana/wallet.js.map +1 -1
- package/build/ui/Popup.d.ts +1 -1
- package/build/ui/Popup.js +1 -1
- package/build/ui/Popup.js.map +1 -1
- package/build/ui/payment/Payment.d.ts +7 -15
- package/build/ui/payment/Payment.js +47 -61
- package/build/ui/payment/Payment.js.map +1 -1
- package/build/ui/payment/Stepper.d.ts +13 -0
- package/build/ui/payment/Stepper.js +22 -0
- package/build/ui/payment/Stepper.js.map +1 -0
- package/build/ui/router.d.ts +6 -3
- package/build/ui/router.js +6 -6
- package/build/ui/router.js.map +1 -1
- package/package.json +1 -1
- package/src/OmniConnector.ts +1 -0
- package/src/core/Intents.ts +92 -46
- package/src/core/api.ts +26 -4
- package/src/cosmos/connector.ts +20 -24
- package/src/cosmos/wallet.ts +0 -1
- package/src/exchange.ts +2 -5
- package/src/solana/wallet.ts +1 -2
- package/src/ui/Popup.tsx +7 -4
- package/src/ui/payment/Payment.tsx +77 -106
- package/src/ui/payment/Stepper.tsx +50 -0
- package/src/ui/router.tsx +13 -11
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { observer } from "mobx-react-lite";
|
|
2
|
-
import
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
3
|
|
|
4
|
+
import { WalletIcon } from "../icons/wallet";
|
|
5
|
+
import { PopupButton, PopupOption, PopupOptionInfo } from "../styles";
|
|
4
6
|
import { Commitment, formatter, Intents } from "../../core";
|
|
5
7
|
import { Recipient } from "../../core/recipient";
|
|
6
8
|
import { Network } from "../../core/chains";
|
|
7
9
|
import { Token } from "../../core/token";
|
|
8
|
-
import { api } from "../../core/api";
|
|
9
10
|
|
|
10
11
|
import { BridgeReview } from "../../exchange";
|
|
11
12
|
import { openConnector } from "../router";
|
|
@@ -15,15 +16,14 @@ import { HotConnector } from "../../HotConnector";
|
|
|
15
16
|
import Popup from "../Popup";
|
|
16
17
|
|
|
17
18
|
import { TokenCard, TokenIcon } from "./TokenCard";
|
|
18
|
-
import {
|
|
19
|
-
import { WalletIcon } from "../icons/wallet";
|
|
19
|
+
import { HorizontalStepper } from "./Stepper";
|
|
20
20
|
import { Loader } from "./Profile";
|
|
21
21
|
|
|
22
22
|
interface PaymentProps {
|
|
23
23
|
intents: Intents;
|
|
24
24
|
connector: HotConnector;
|
|
25
|
-
|
|
26
|
-
onConfirm: (
|
|
25
|
+
onReject: (message: string) => void;
|
|
26
|
+
onConfirm: (args: { depositQoute: BridgeReview | "direct"; processing?: () => Promise<BridgeReview> }) => void;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
const animations = {
|
|
@@ -32,56 +32,9 @@ const animations = {
|
|
|
32
32
|
loading: "https://hex.exchange/loading.json",
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
label: string;
|
|
37
|
-
completed?: boolean;
|
|
38
|
-
active?: boolean;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
interface StepperProps {
|
|
42
|
-
steps: Step[];
|
|
43
|
-
currentStep: number;
|
|
44
|
-
style?: React.CSSProperties;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export const HorizontalStepper: React.FC<StepperProps> = ({ steps, currentStep, style }) => {
|
|
48
|
-
return (
|
|
49
|
-
<div style={{ padding: "0 32px 32px", display: "flex", alignItems: "center", width: "100%", margin: "16px 0", ...style }}>
|
|
50
|
-
{steps.map((step, idx) => {
|
|
51
|
-
const isCompleted = idx < currentStep;
|
|
52
|
-
const isActive = idx === currentStep;
|
|
53
|
-
|
|
54
|
-
return (
|
|
55
|
-
<React.Fragment key={idx}>
|
|
56
|
-
<div style={{ display: "flex", flexDirection: "column", alignItems: "center" }}>
|
|
57
|
-
<div
|
|
58
|
-
style={{
|
|
59
|
-
width: 16,
|
|
60
|
-
height: 16,
|
|
61
|
-
position: "relative",
|
|
62
|
-
borderRadius: "50%",
|
|
63
|
-
border: isActive || isCompleted ? "2px solid #ffffff" : "2px solid #a0a0a0",
|
|
64
|
-
background: isCompleted ? "#ffffff" : "#333",
|
|
65
|
-
display: "flex",
|
|
66
|
-
alignItems: "center",
|
|
67
|
-
justifyContent: "center",
|
|
68
|
-
transition: "all 0.2s",
|
|
69
|
-
zIndex: 1,
|
|
70
|
-
}}
|
|
71
|
-
>
|
|
72
|
-
<p style={{ fontSize: 16, color: "#fff", opacity: isActive ? 1 : 0.5, position: "absolute", top: 24, width: 100 }}>{step.label}</p>
|
|
73
|
-
</div>
|
|
74
|
-
</div>
|
|
75
|
-
|
|
76
|
-
{idx < steps.length - 1 && <div style={{ transition: "background 0.2s", flex: 1, height: 2, background: idx < currentStep ? "#ffffff" : "#333", margin: "0 6px", borderRadius: 24, minWidth: 24 }} />}
|
|
77
|
-
</React.Fragment>
|
|
78
|
-
);
|
|
79
|
-
})}
|
|
80
|
-
</div>
|
|
81
|
-
);
|
|
82
|
-
};
|
|
35
|
+
const PAY_SLIPPAGE = 0.002;
|
|
83
36
|
|
|
84
|
-
export const Payment = observer(({ connector, intents,
|
|
37
|
+
export const Payment = observer(({ connector, intents, onReject, onConfirm }: PaymentProps) => {
|
|
85
38
|
useState(() => {
|
|
86
39
|
fetch(animations.loading);
|
|
87
40
|
fetch(animations.success);
|
|
@@ -97,10 +50,9 @@ export const Payment = observer(({ connector, intents, onClose, onConfirm }: Pay
|
|
|
97
50
|
token?: Token;
|
|
98
51
|
wallet?: OmniWallet;
|
|
99
52
|
commitment?: Commitment;
|
|
100
|
-
review?: BridgeReview;
|
|
101
|
-
|
|
53
|
+
review?: BridgeReview | "direct";
|
|
54
|
+
success?: { depositQoute: BridgeReview | "direct"; processing?: () => Promise<BridgeReview> };
|
|
102
55
|
step?: "selectToken" | "sign" | "transfer" | "success" | "error" | "loading";
|
|
103
|
-
success?: boolean;
|
|
104
56
|
loading?: boolean;
|
|
105
57
|
error?: any;
|
|
106
58
|
} | null>(null);
|
|
@@ -112,26 +64,37 @@ export const Payment = observer(({ connector, intents, onClose, onConfirm }: Pay
|
|
|
112
64
|
const selectToken = async (from: Token, wallet?: OmniWallet) => {
|
|
113
65
|
if (!wallet) return;
|
|
114
66
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
67
|
+
// Set signer as payer wallet if not set another
|
|
68
|
+
if (!intents.signer) intents.attachWallet(wallet);
|
|
69
|
+
|
|
70
|
+
if (from.id === need.id) {
|
|
71
|
+
return setFlow({ token: from, wallet, review: "direct", step: "sign" });
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
setFlow({ token: from, wallet, review: undefined, step: "sign" });
|
|
76
|
+
const review = await connector.exchange.reviewSwap({
|
|
77
|
+
recipient: Recipient.fromWallet(intents.signer)!,
|
|
78
|
+
amount: needAmount + (needAmount * BigInt(Math.floor(PAY_SLIPPAGE * 1000))) / BigInt(1000),
|
|
79
|
+
slippage: PAY_SLIPPAGE,
|
|
80
|
+
sender: wallet,
|
|
81
|
+
refund: wallet,
|
|
82
|
+
type: "exactOut",
|
|
83
|
+
to: need,
|
|
84
|
+
from,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
setFlow({ token: from, wallet, review, step: "sign" });
|
|
88
|
+
} catch {
|
|
89
|
+
setFlow({ token: from, wallet, error: true, step: "sign" });
|
|
90
|
+
}
|
|
128
91
|
};
|
|
129
92
|
|
|
130
93
|
const signStep = async () => {
|
|
131
94
|
try {
|
|
132
95
|
setFlow((t) => (t ? { ...t, step: "sign", loading: true } : null));
|
|
133
|
-
|
|
134
|
-
setFlow((t) => (t ? { ...t, step: "transfer",
|
|
96
|
+
await intents.sign();
|
|
97
|
+
setFlow((t) => (t ? { ...t, step: "transfer", loading: false } : null));
|
|
135
98
|
} catch (error) {
|
|
136
99
|
console.error(error);
|
|
137
100
|
setFlow((t) => (t ? { ...t, step: "error", loading: false, error } : null));
|
|
@@ -141,22 +104,19 @@ export const Payment = observer(({ connector, intents, onClose, onConfirm }: Pay
|
|
|
141
104
|
|
|
142
105
|
const confirmPaymentStep = async () => {
|
|
143
106
|
try {
|
|
144
|
-
const commitment = flow?.commitment;
|
|
145
|
-
if (!commitment) throw new Error("Commitment not found");
|
|
146
107
|
if (!flow?.review) throw new Error("Review not found");
|
|
147
|
-
|
|
148
108
|
setFlow((t) => (t ? { ...t, step: "loading" } : null));
|
|
149
|
-
const result = await connector.exchange.makeSwap(flow.review, { log: () => {} });
|
|
150
109
|
|
|
151
|
-
if (
|
|
152
|
-
|
|
153
|
-
setFlow((t) => (t ? { ...t, step: "success", loading: false, success: true } : null));
|
|
154
|
-
return data;
|
|
155
|
-
} else {
|
|
156
|
-
const hash = await Intents.publish([commitment]);
|
|
157
|
-
setFlow((t) => (t ? { ...t, step: "success", loading: false, success: true } : null));
|
|
158
|
-
return { hash };
|
|
110
|
+
if (flow.review == "direct") {
|
|
111
|
+
return setFlow({ step: "success", loading: false, success: { depositQoute: "direct" } });
|
|
159
112
|
}
|
|
113
|
+
|
|
114
|
+
const result = await connector.exchange.makeSwap(flow.review, { log: () => {} });
|
|
115
|
+
setFlow({
|
|
116
|
+
loading: false,
|
|
117
|
+
step: "success",
|
|
118
|
+
success: { depositQoute: result.review, processing: result.processing },
|
|
119
|
+
});
|
|
160
120
|
} catch (error) {
|
|
161
121
|
console.error(error);
|
|
162
122
|
setFlow((t) => (t ? { ...t, step: "error", loading: false, error } : null));
|
|
@@ -166,13 +126,13 @@ export const Payment = observer(({ connector, intents, onClose, onConfirm }: Pay
|
|
|
166
126
|
|
|
167
127
|
if (flow?.step === "success") {
|
|
168
128
|
return (
|
|
169
|
-
<Popup
|
|
129
|
+
<Popup header={<p>{title}</p>}>
|
|
170
130
|
<div style={{ width: "100%", height: 400, display: "flex", justifyContent: "center", alignItems: "center", flexDirection: "column" }}>
|
|
171
131
|
{/* @ts-expect-error: dotlottie-wc is not typed */}
|
|
172
132
|
<dotlottie-wc key="success" src={animations.success} speed="1" style={{ width: 300, height: 300 }} mode="forward" loop autoplay></dotlottie-wc>
|
|
173
133
|
<p style={{ fontSize: 24, marginTop: -32, fontWeight: "bold" }}>Payment successful</p>
|
|
174
134
|
</div>
|
|
175
|
-
<PopupButton style={{ marginTop: "auto" }} onClick={() =>
|
|
135
|
+
<PopupButton style={{ marginTop: "auto" }} onClick={() => onConfirm(flow.success!)}>
|
|
176
136
|
Continue
|
|
177
137
|
</PopupButton>
|
|
178
138
|
</Popup>
|
|
@@ -181,7 +141,7 @@ export const Payment = observer(({ connector, intents, onClose, onConfirm }: Pay
|
|
|
181
141
|
|
|
182
142
|
if (flow?.step === "loading") {
|
|
183
143
|
return (
|
|
184
|
-
<Popup
|
|
144
|
+
<Popup header={<p>{title}</p>}>
|
|
185
145
|
<div style={{ width: "100%", height: 400, display: "flex", justifyContent: "center", alignItems: "center", flexDirection: "column" }}>
|
|
186
146
|
{/* @ts-expect-error: dotlottie-wc is not typed */}
|
|
187
147
|
<dotlottie-wc key="loading" src={animations.loading} speed="1" style={{ marginTop: -64, width: 300, height: 300 }} mode="forward" loop autoplay></dotlottie-wc>
|
|
@@ -193,14 +153,14 @@ export const Payment = observer(({ connector, intents, onClose, onConfirm }: Pay
|
|
|
193
153
|
|
|
194
154
|
if (flow?.step === "error") {
|
|
195
155
|
return (
|
|
196
|
-
<Popup
|
|
156
|
+
<Popup header={<p>{title}</p>}>
|
|
197
157
|
<div style={{ width: "100%", height: 400, gap: 8, display: "flex", justifyContent: "center", alignItems: "center", flexDirection: "column" }}>
|
|
198
158
|
{/* @ts-expect-error: dotlottie-wc is not typed */}
|
|
199
159
|
<dotlottie-wc key="error" src={animations.failed} speed="1" style={{ width: 300, height: 300 }} mode="forward" loop autoplay></dotlottie-wc>
|
|
200
160
|
<p style={{ fontSize: 24, marginTop: -32, fontWeight: "bold" }}>Payment failed</p>
|
|
201
|
-
<p style={{ fontSize: 14 }}>{flow.error?.toString?.() ?? "Unknown error"}</p>
|
|
161
|
+
<p style={{ fontSize: 14, width: "80%", textAlign: "center", overflowY: "auto", lineBreak: "anywhere" }}>{flow.error?.toString?.() ?? "Unknown error"}</p>
|
|
202
162
|
</div>
|
|
203
|
-
<PopupButton onClick={() =>
|
|
163
|
+
<PopupButton onClick={() => onReject(flow.error?.toString?.() ?? "Unknown error")}>Close</PopupButton>
|
|
204
164
|
</Popup>
|
|
205
165
|
);
|
|
206
166
|
}
|
|
@@ -209,7 +169,7 @@ export const Payment = observer(({ connector, intents, onClose, onConfirm }: Pay
|
|
|
209
169
|
if (!flow.token) return null;
|
|
210
170
|
if (!flow.wallet) return null;
|
|
211
171
|
return (
|
|
212
|
-
<Popup onClose={
|
|
172
|
+
<Popup onClose={() => onReject("closed")} header={<p>{title}</p>}>
|
|
213
173
|
<HorizontalStepper steps={[{ label: "Select" }, { label: "Review" }, { label: "Confirm" }]} currentStep={2} />
|
|
214
174
|
|
|
215
175
|
<PopupOption style={{ marginTop: 8 }}>
|
|
@@ -222,8 +182,8 @@ export const Payment = observer(({ connector, intents, onClose, onConfirm }: Pay
|
|
|
222
182
|
|
|
223
183
|
{flow.review ? (
|
|
224
184
|
<div style={{ paddingRight: 4, marginLeft: "auto", alignItems: "flex-end" }}>
|
|
225
|
-
<p style={{ textAlign: "right", fontSize: 20 }}>{flow.token.readable(flow.review?.amountIn ?? 0)}</p>
|
|
226
|
-
<p style={{ textAlign: "right", fontSize: 14, color: "#c6c6c6" }}>${flow.token.readable(flow.review?.amountIn ?? 0n, flow.token.usd)}</p>
|
|
185
|
+
<p style={{ textAlign: "right", fontSize: 20 }}>{flow.token.readable(flow.review === "direct" ? needAmount : flow.review?.amountIn ?? 0)}</p>
|
|
186
|
+
<p style={{ textAlign: "right", fontSize: 14, color: "#c6c6c6" }}>${flow.token.readable(flow.review === "direct" ? needAmount : flow.review?.amountIn ?? 0n, flow.token.usd)}</p>
|
|
227
187
|
</div>
|
|
228
188
|
) : (
|
|
229
189
|
<div style={{ paddingRight: 4, marginLeft: "auto", alignItems: "flex-end" }}>
|
|
@@ -232,7 +192,7 @@ export const Payment = observer(({ connector, intents, onClose, onConfirm }: Pay
|
|
|
232
192
|
)}
|
|
233
193
|
</PopupOption>
|
|
234
194
|
|
|
235
|
-
<PopupButton style={{ marginTop: 24 }} disabled={!flow?.review} onClick={
|
|
195
|
+
<PopupButton style={{ marginTop: 24 }} disabled={!flow?.review} onClick={confirmPaymentStep}>
|
|
236
196
|
{flow?.loading ? "Confirming..." : "Confirm payment"}
|
|
237
197
|
</PopupButton>
|
|
238
198
|
</Popup>
|
|
@@ -243,7 +203,7 @@ export const Payment = observer(({ connector, intents, onClose, onConfirm }: Pay
|
|
|
243
203
|
if (!flow.token) return null;
|
|
244
204
|
if (!flow.wallet) return null;
|
|
245
205
|
return (
|
|
246
|
-
<Popup onClose={
|
|
206
|
+
<Popup onClose={() => onReject("closed")} header={<p>{title}</p>}>
|
|
247
207
|
<HorizontalStepper steps={[{ label: "Select" }, { label: "Review" }, { label: "Confirm" }]} currentStep={1} />
|
|
248
208
|
|
|
249
209
|
<PopupOption style={{ marginTop: 8 }}>
|
|
@@ -256,40 +216,51 @@ export const Payment = observer(({ connector, intents, onClose, onConfirm }: Pay
|
|
|
256
216
|
|
|
257
217
|
{flow.review ? (
|
|
258
218
|
<div style={{ paddingRight: 4, marginLeft: "auto", alignItems: "flex-end" }}>
|
|
259
|
-
<p style={{ textAlign: "right", fontSize: 20 }}>{flow.token.readable(flow.review?.amountIn ?? 0)}</p>
|
|
260
|
-
<p style={{ textAlign: "right", fontSize: 14, color: "#c6c6c6" }}>${flow.token.readable(flow.review?.amountIn ?? 0n, flow.token.usd)}</p>
|
|
219
|
+
<p style={{ textAlign: "right", fontSize: 20 }}>{flow.token.readable(flow.review === "direct" ? needAmount : flow.review?.amountIn ?? 0)}</p>
|
|
220
|
+
<p style={{ textAlign: "right", fontSize: 14, color: "#c6c6c6" }}>${flow.token.readable(flow.review === "direct" ? needAmount : flow.review?.amountIn ?? 0n, flow.token.usd)}</p>
|
|
261
221
|
</div>
|
|
262
222
|
) : (
|
|
263
223
|
<div style={{ paddingRight: 4, marginLeft: "auto", alignItems: "flex-end" }}>
|
|
264
|
-
|
|
224
|
+
{flow.error ? (
|
|
225
|
+
<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg" aria-label="Failed" style={{ display: "block", margin: "0 auto" }}>
|
|
226
|
+
<circle cx="14" cy="14" r="13" stroke="#E74C3C" strokeWidth="2" />
|
|
227
|
+
<path d="M9 9l10 10M19 9l-10 10" stroke="#E74C3C" strokeWidth="2.5" strokeLinecap="round" />
|
|
228
|
+
</svg>
|
|
229
|
+
) : (
|
|
230
|
+
<Loader />
|
|
231
|
+
)}
|
|
265
232
|
</div>
|
|
266
233
|
)}
|
|
267
234
|
</PopupOption>
|
|
268
235
|
|
|
269
|
-
|
|
270
|
-
{
|
|
271
|
-
|
|
236
|
+
{flow.error ? (
|
|
237
|
+
<PopupButton style={{ marginTop: 24 }} onClick={() => setFlow(null)}>
|
|
238
|
+
Select another token
|
|
239
|
+
</PopupButton>
|
|
240
|
+
) : (
|
|
241
|
+
<PopupButton style={{ marginTop: 24 }} disabled={!flow?.review} onClick={signStep}>
|
|
242
|
+
{flow?.loading ? "Signing..." : flow?.review ? "Sign review" : "Quoting..."}
|
|
243
|
+
</PopupButton>
|
|
244
|
+
)}
|
|
272
245
|
</Popup>
|
|
273
246
|
);
|
|
274
247
|
}
|
|
275
248
|
|
|
276
249
|
return (
|
|
277
|
-
<Popup onClose={
|
|
250
|
+
<Popup onClose={() => onReject("closed")} header={<p>{title}</p>}>
|
|
278
251
|
<HorizontalStepper steps={[{ label: "Select" }, { label: "Review" }, { label: "Confirm" }]} currentStep={0} />
|
|
279
252
|
|
|
280
253
|
{connector.walletsTokens.map(({ token, wallet, balance }) => {
|
|
281
|
-
if (token.id === need.id) return null;
|
|
282
254
|
const availableBalance = token.float(balance) - token.reserve;
|
|
283
255
|
|
|
284
256
|
if (need.originalChain === Network.Gonka || need.originalChain === Network.Juno) {
|
|
285
257
|
if (token.id === need.id) return null;
|
|
286
258
|
if (token.originalAddress !== need.originalAddress) return null;
|
|
287
|
-
|
|
288
259
|
if (availableBalance < need.float(needAmount)) return null;
|
|
289
260
|
return <TokenCard key={token.id} token={token} onSelect={selectToken} hot={connector} wallet={wallet} />;
|
|
290
261
|
}
|
|
291
262
|
|
|
292
|
-
if (availableBalance * token.usd <= need.usd * need.float(needAmount)) return null;
|
|
263
|
+
if (availableBalance * token.usd <= need.usd * need.float(needAmount) * (1 + PAY_SLIPPAGE)) return null;
|
|
293
264
|
return <TokenCard key={token.id} token={token} onSelect={selectToken} hot={connector} wallet={wallet} />;
|
|
294
265
|
})}
|
|
295
266
|
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
interface Step {
|
|
4
|
+
label: string;
|
|
5
|
+
completed?: boolean;
|
|
6
|
+
active?: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface StepperProps {
|
|
10
|
+
steps: Step[];
|
|
11
|
+
currentStep: number;
|
|
12
|
+
style?: React.CSSProperties;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const HorizontalStepper: React.FC<StepperProps> = ({ steps, currentStep, style }) => {
|
|
16
|
+
return (
|
|
17
|
+
<div style={{ padding: "0 32px 32px", display: "flex", alignItems: "center", width: "100%", margin: "16px 0", ...style }}>
|
|
18
|
+
{steps.map((step, idx) => {
|
|
19
|
+
const isCompleted = idx < currentStep;
|
|
20
|
+
const isActive = idx === currentStep;
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<React.Fragment key={idx}>
|
|
24
|
+
<div style={{ display: "flex", flexDirection: "column", alignItems: "center" }}>
|
|
25
|
+
<div
|
|
26
|
+
style={{
|
|
27
|
+
width: 16,
|
|
28
|
+
height: 16,
|
|
29
|
+
position: "relative",
|
|
30
|
+
borderRadius: "50%",
|
|
31
|
+
border: isActive || isCompleted ? "2px solid #ffffff" : "2px solid #a0a0a0",
|
|
32
|
+
background: isCompleted ? "#ffffff" : "#333",
|
|
33
|
+
display: "flex",
|
|
34
|
+
alignItems: "center",
|
|
35
|
+
justifyContent: "center",
|
|
36
|
+
transition: "all 0.2s",
|
|
37
|
+
zIndex: 1,
|
|
38
|
+
}}
|
|
39
|
+
>
|
|
40
|
+
<p style={{ fontSize: 16, color: "#fff", opacity: isActive ? 1 : 0.5, position: "absolute", top: 24, width: 100 }}>{step.label}</p>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
{idx < steps.length - 1 && <div style={{ transition: "background 0.2s", flex: 1, height: 2, background: idx < currentStep ? "#ffffff" : "#333", margin: "0 6px", borderRadius: 24, minWidth: 24 }} />}
|
|
45
|
+
</React.Fragment>
|
|
46
|
+
);
|
|
47
|
+
})}
|
|
48
|
+
</div>
|
|
49
|
+
);
|
|
50
|
+
};
|
package/src/ui/router.tsx
CHANGED
|
@@ -1,31 +1,33 @@
|
|
|
1
1
|
import { HotConnector } from "../HotConnector";
|
|
2
2
|
import { OmniConnector } from "../OmniConnector";
|
|
3
|
-
import { BridgeReview } from "../exchange";
|
|
4
|
-
import { Token } from "../core/token";
|
|
5
3
|
import { OmniWallet } from "../OmniWallet";
|
|
4
|
+
|
|
5
|
+
import { BridgeReview } from "../exchange";
|
|
6
6
|
import { WalletType } from "../core/chains";
|
|
7
7
|
import { Recipient } from "../core/recipient";
|
|
8
8
|
import { Intents } from "../core/Intents";
|
|
9
|
+
import { Token } from "../core/token";
|
|
9
10
|
|
|
10
11
|
import { present } from "./Popup";
|
|
12
|
+
import { SelectTokenPopup } from "./payment/SelectToken";
|
|
13
|
+
import { SelectRecipient } from "./payment/SelectRecipient";
|
|
14
|
+
import { SelectSender } from "./payment/SelectSender";
|
|
15
|
+
import { BridgeProps } from "./payment/Bridge";
|
|
11
16
|
import { Payment } from "./payment/Payment";
|
|
12
|
-
import { LogoutPopup } from "./connect/LogoutPopup";
|
|
13
|
-
import { Bridge } from "./payment/Bridge";
|
|
14
17
|
import { Profile } from "./payment/Profile";
|
|
15
|
-
import {
|
|
18
|
+
import { Bridge } from "./payment/Bridge";
|
|
19
|
+
|
|
20
|
+
import { LogoutPopup } from "./connect/LogoutPopup";
|
|
16
21
|
import { WalletPicker } from "./connect/WalletPicker";
|
|
17
|
-
import { BridgeProps } from "./payment/Bridge";
|
|
18
22
|
import { Connector } from "./connect/ConnectWallet";
|
|
19
|
-
import { SelectSender } from "./payment/SelectSender";
|
|
20
|
-
import { SelectRecipient } from "./payment/SelectRecipient";
|
|
21
23
|
import { WCRequest } from "./connect/WCRequest";
|
|
22
24
|
|
|
23
25
|
export const openPayment = (connector: HotConnector, intents: Intents) => {
|
|
24
|
-
return new Promise<Promise<
|
|
26
|
+
return new Promise<{ depositQoute: BridgeReview | "direct"; processing?: () => Promise<BridgeReview> }>((resolve, reject) => {
|
|
25
27
|
present((close) => (
|
|
26
28
|
<Payment //
|
|
27
|
-
|
|
28
|
-
onConfirm={resolve}
|
|
29
|
+
onReject={() => (close(), reject(new Error("User rejected")))}
|
|
30
|
+
onConfirm={(args) => (close(), resolve(args))}
|
|
29
31
|
connector={connector}
|
|
30
32
|
intents={intents}
|
|
31
33
|
/>
|