@hot-labs/kit 1.6.0 → 1.6.2
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/activity.d.ts +4 -0
- package/build/activity.js +20 -1
- package/build/activity.js.map +1 -1
- package/build/core/defuse.d.ts +61 -0
- package/build/core/defuse.js +47 -0
- package/build/core/defuse.js.map +1 -0
- package/build/core/exchange.d.ts +8 -4
- package/build/core/exchange.js +33 -7
- package/build/core/exchange.js.map +1 -1
- package/build/core/pendings.d.ts +37 -12
- package/build/core/pendings.js +70 -35
- package/build/core/pendings.js.map +1 -1
- package/build/ui/bridge/Bridge.js +11 -186
- package/build/ui/bridge/Bridge.js.map +1 -1
- package/build/ui/bridge/SelectSender.d.ts +2 -1
- package/build/ui/bridge/SelectSender.js +10 -2
- package/build/ui/bridge/SelectSender.js.map +1 -1
- package/build/ui/bridge/SelectToken.d.ts +2 -1
- package/build/ui/bridge/SelectToken.js +14 -6
- package/build/ui/bridge/SelectToken.js.map +1 -1
- package/build/ui/bridge/TokenAmountCard.d.ts +39 -0
- package/build/ui/bridge/TokenAmountCard.js +186 -0
- package/build/ui/bridge/TokenAmountCard.js.map +1 -0
- package/build/ui/icons/warning.js +1 -1
- package/build/ui/icons/warning.js.map +1 -1
- package/build/ui/profile/DepositFlow.d.ts +3 -0
- package/build/ui/profile/DepositFlow.js +128 -9
- package/build/ui/profile/DepositFlow.js.map +1 -1
- package/build/ui/profile/DepositQR.d.ts +11 -4
- package/build/ui/profile/DepositQR.js +82 -38
- package/build/ui/profile/DepositQR.js.map +1 -1
- package/build/ui/profile/Payment.js +3 -9
- package/build/ui/profile/Payment.js.map +1 -1
- package/build/ui/profile/Profile.d.ts +8 -3
- package/build/ui/profile/Profile.js +15 -9
- package/build/ui/profile/Profile.js.map +1 -1
- package/build/ui/router.d.ts +4 -2
- package/build/ui/router.js +4 -6
- package/build/ui/router.js.map +1 -1
- package/build/ui/styles.js +2 -1
- package/build/ui/styles.js.map +1 -1
- package/build/ui/toast/index.js +2 -0
- package/build/ui/toast/index.js.map +1 -1
- package/build/ui/uikit/animationts.d.ts +5 -0
- package/build/ui/uikit/animationts.js +19 -0
- package/build/ui/uikit/animationts.js.map +1 -0
- package/build/ui/uikit/badge.d.ts +5 -0
- package/build/ui/uikit/badge.js +19 -0
- package/build/ui/uikit/badge.js.map +1 -0
- package/build/ui/uikit/tabs.d.ts +2 -1
- package/build/ui/uikit/tabs.js +31 -17
- package/build/ui/uikit/tabs.js.map +1 -1
- package/package.json +1 -1
- package/src/activity.ts +22 -1
- package/src/core/defuse.ts +102 -0
- package/src/core/exchange.ts +38 -10
- package/src/core/pendings.ts +81 -38
- package/src/ui/bridge/Bridge.tsx +30 -312
- package/src/ui/bridge/SelectSender.tsx +24 -2
- package/src/ui/bridge/SelectToken.tsx +15 -6
- package/src/ui/bridge/TokenAmountCard.tsx +347 -0
- package/src/ui/icons/warning.tsx +1 -1
- package/src/ui/profile/DepositFlow.tsx +286 -10
- package/src/ui/profile/DepositQR.tsx +196 -76
- package/src/ui/profile/Payment.tsx +4 -27
- package/src/ui/profile/Profile.tsx +100 -91
- package/src/ui/router.tsx +5 -7
- package/src/ui/styles.ts +2 -1
- package/src/ui/toast/index.tsx +2 -0
- package/src/ui/uikit/animationts.ts +20 -0
- package/src/ui/uikit/badge.tsx +24 -0
- package/src/ui/uikit/tabs.tsx +38 -24
package/src/ui/bridge/Bridge.tsx
CHANGED
|
@@ -5,7 +5,6 @@ import uuid4 from "uuid4";
|
|
|
5
5
|
|
|
6
6
|
import { ArrowRightIcon } from "../icons/arrow-right";
|
|
7
7
|
import ExchangeIcon from "../icons/exchange";
|
|
8
|
-
import RefreshIcon from "../icons/refresh";
|
|
9
8
|
|
|
10
9
|
import { HotKit } from "../../HotKit";
|
|
11
10
|
import { chains, Network, WalletType } from "../../core/chains";
|
|
@@ -16,21 +15,15 @@ import { formatter } from "../../core/utils";
|
|
|
16
15
|
import { tokens } from "../../core/tokens";
|
|
17
16
|
import { Token } from "../../core/token";
|
|
18
17
|
|
|
19
|
-
import {
|
|
20
|
-
import { H5,
|
|
18
|
+
import { useAnimations } from "../uikit/animationts";
|
|
19
|
+
import { H5, PSmall, PTiny } from "../uikit/text";
|
|
20
|
+
import { ActionButton } from "../uikit/button";
|
|
21
21
|
import { Skeleton } from "../uikit/loader";
|
|
22
22
|
import { ImageView } from "../uikit/image";
|
|
23
23
|
|
|
24
24
|
import Popup from "../Popup";
|
|
25
|
-
import { openConnector, openSelectRecipient, openSelectSender, openSelectTokenPopup } from "../router";
|
|
26
25
|
import DepositQR from "../profile/DepositQR";
|
|
27
|
-
import {
|
|
28
|
-
|
|
29
|
-
const animations = {
|
|
30
|
-
success: "https://hex.exchange/success.json",
|
|
31
|
-
failed: "https://hex.exchange/error.json",
|
|
32
|
-
loading: "https://hex.exchange/loading.json",
|
|
33
|
-
};
|
|
26
|
+
import { BadgeButton, Card, CardBody, CardHeader, ChainButton, TokenAmountCard, TokenPreview, Tooltip } from "./TokenAmountCard";
|
|
34
27
|
|
|
35
28
|
export interface ProcessingState {
|
|
36
29
|
status: "qr" | "processing" | "success" | "error";
|
|
@@ -74,13 +67,8 @@ export const Bridge = observer(({ kit, widget, setup, onClose, onProcess, onStat
|
|
|
74
67
|
const [isError, setIsError] = useState<string | null>(null);
|
|
75
68
|
const [isReviewing, setIsReviewing] = useState(false);
|
|
76
69
|
|
|
77
|
-
useState(() => {
|
|
78
|
-
fetch(animations.loading);
|
|
79
|
-
fetch(animations.success);
|
|
80
|
-
fetch(animations.failed);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
70
|
const [processing, setProcessing] = useState<ProcessingState | null>(null);
|
|
71
|
+
const animations = useAnimations();
|
|
84
72
|
|
|
85
73
|
useEffect(() => {
|
|
86
74
|
onStateUpdate?.(processing);
|
|
@@ -243,14 +231,16 @@ export const Bridge = observer(({ kit, widget, setup, onClose, onProcess, onStat
|
|
|
243
231
|
}
|
|
244
232
|
};
|
|
245
233
|
|
|
246
|
-
if (processing?.status === "qr") {
|
|
234
|
+
if (processing?.status === "qr" && typeof processing.review.qoute === "object") {
|
|
247
235
|
return (
|
|
248
236
|
<Popup widget={widget} onClose={onClose} header={<p>{title}</p>} mobileFullscreen={setup?.mobileFullscreen}>
|
|
249
237
|
<DepositQR //
|
|
250
|
-
|
|
251
|
-
|
|
238
|
+
depositAmount={processing.review.qoute.amountInFormatted}
|
|
239
|
+
depositAddress={processing.review.qoute.depositAddress!}
|
|
252
240
|
onConfirm={() => onProcess(process(processing.review))}
|
|
253
241
|
onCancel={cancelReview}
|
|
242
|
+
token={from}
|
|
243
|
+
kit={kit}
|
|
254
244
|
/>
|
|
255
245
|
</Popup>
|
|
256
246
|
);
|
|
@@ -302,9 +292,9 @@ export const Bridge = observer(({ kit, widget, setup, onClose, onProcess, onStat
|
|
|
302
292
|
}
|
|
303
293
|
|
|
304
294
|
const button = () => {
|
|
305
|
-
if (refundWallet == null) return <ActionButton onClick={() => openConnector(kit)}>Sign in to HEX</ActionButton>;
|
|
306
295
|
if (sender == null) return <ActionButton disabled>Confirm</ActionButton>;
|
|
307
296
|
if (recipient == null) return <ActionButton disabled>Confirm</ActionButton>;
|
|
297
|
+
if (refundWallet == null) return <ActionButton onClick={() => kit.router.openConnector(kit)}>Sign in to HEX</ActionButton>;
|
|
308
298
|
if (sender !== "qr" && +from.float(kit.balance(sender, from)).toFixed(FIXED) < +amountFrom.toFixed(FIXED)) return <ActionButton disabled>Insufficient balance</ActionButton>;
|
|
309
299
|
return (
|
|
310
300
|
<ActionButton style={{ width: "100%", marginTop: 40 }} disabled={isReviewing || isError != null} onClick={handleConfirm}>
|
|
@@ -316,118 +306,22 @@ export const Bridge = observer(({ kit, widget, setup, onClose, onProcess, onStat
|
|
|
316
306
|
return (
|
|
317
307
|
<Popup widget={widget} onClose={onClose} header={<p>{title}</p>} mobileFullscreen={setup?.mobileFullscreen} style={{ background: "#191919" }}>
|
|
318
308
|
<div style={{ display: "flex", flexDirection: "column", gap: 4, width: "100%", height: "100%" }}>
|
|
319
|
-
<
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
</BadgeButton>
|
|
336
|
-
</div>
|
|
337
|
-
</CardHeader>
|
|
338
|
-
|
|
339
|
-
<CardBody>
|
|
340
|
-
<div style={{ width: "100%", display: "flex", alignItems: "center", gap: 8, justifyContent: "space-between" }}>
|
|
341
|
-
<TokenPreview
|
|
342
|
-
token={from}
|
|
343
|
-
onSelect={() =>
|
|
344
|
-
openSelectTokenPopup({
|
|
345
|
-
onSelect: (token, wallet) => (setFrom(token), setSender(wallet)),
|
|
346
|
-
initialChain: from.chain,
|
|
347
|
-
kit,
|
|
348
|
-
})
|
|
349
|
-
}
|
|
350
|
-
/>
|
|
351
|
-
|
|
352
|
-
{isReviewing && type === "exactOut" ? (
|
|
353
|
-
<Skeleton />
|
|
354
|
-
) : (
|
|
355
|
-
<input //
|
|
356
|
-
name="from"
|
|
357
|
-
type="text"
|
|
358
|
-
className="input"
|
|
359
|
-
autoComplete="off"
|
|
360
|
-
autoCapitalize="off"
|
|
361
|
-
autoCorrect="off"
|
|
362
|
-
readOnly={setup?.readonlyAmount}
|
|
363
|
-
value={isFiat ? `$${showAmountFrom}` : showAmountFrom}
|
|
364
|
-
onChange={(e) => (setType("exactIn"), setValue(e.target.value))}
|
|
365
|
-
placeholder="0"
|
|
366
|
-
autoFocus
|
|
367
|
-
/>
|
|
368
|
-
)}
|
|
369
|
-
</div>
|
|
370
|
-
|
|
371
|
-
{isFiat && (
|
|
372
|
-
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", width: "100%" }}>
|
|
373
|
-
{sender !== "qr" && (
|
|
374
|
-
<AvailableBalance>
|
|
375
|
-
<PSmall>Balance: ${from.readable(availableBalance, from.usd)}</PSmall>
|
|
376
|
-
<Button onClick={() => sender && kit.fetchToken(from, sender)}>
|
|
377
|
-
<RefreshIcon color="#fff" />
|
|
378
|
-
</Button>
|
|
379
|
-
</AvailableBalance>
|
|
380
|
-
)}
|
|
381
|
-
|
|
382
|
-
{sender === "qr" && <div />}
|
|
383
|
-
|
|
384
|
-
<div style={{ display: "flex", alignItems: "center", gap: 4, flexShrink: 0 }}>
|
|
385
|
-
{from.usd !== 0 && <PSmall style={{ marginRight: 8 }}>{`${from.readable(amountFrom / from.usd)} ${from.symbol}`}</PSmall>}
|
|
386
|
-
|
|
387
|
-
{from.usd !== 0 && (
|
|
388
|
-
<BadgeButton style={{ border: `1px solid #fff` }} onClick={() => setIsFiat(!isFiat)}>
|
|
389
|
-
<PTiny>USD</PTiny>
|
|
390
|
-
</BadgeButton>
|
|
391
|
-
)}
|
|
392
|
-
|
|
393
|
-
{sender !== "qr" && (
|
|
394
|
-
<BadgeButton onClick={handleMax}>
|
|
395
|
-
<PTiny>MAX</PTiny>
|
|
396
|
-
</BadgeButton>
|
|
397
|
-
)}
|
|
398
|
-
</div>
|
|
399
|
-
</div>
|
|
400
|
-
)}
|
|
401
|
-
|
|
402
|
-
{!isFiat && (
|
|
403
|
-
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", width: "100%" }}>
|
|
404
|
-
{sender !== "qr" && (
|
|
405
|
-
<AvailableBalance>
|
|
406
|
-
<PSmall>Balance: {`${from.readable(availableBalance)} ${from.symbol}`}</PSmall>
|
|
407
|
-
<Button style={{ marginTop: 2 }} onClick={() => sender && kit.fetchToken(from, sender)}>
|
|
408
|
-
<RefreshIcon color="#fff" />
|
|
409
|
-
</Button>
|
|
410
|
-
</AvailableBalance>
|
|
411
|
-
)}
|
|
412
|
-
|
|
413
|
-
{sender === "qr" && <div />}
|
|
414
|
-
<div style={{ display: "flex", alignItems: "center", gap: 4 }}>
|
|
415
|
-
{from.usd !== 0 && <PSmall style={{ marginRight: 8 }}>${from.readable(amountFrom, from.usd)}</PSmall>}
|
|
416
|
-
{from.usd !== 0 && (
|
|
417
|
-
<BadgeButton onClick={() => setIsFiat(!isFiat)}>
|
|
418
|
-
<PTiny>USD</PTiny>
|
|
419
|
-
</BadgeButton>
|
|
420
|
-
)}
|
|
421
|
-
{sender !== "qr" && (
|
|
422
|
-
<BadgeButton onClick={handleMax}>
|
|
423
|
-
<PTiny>MAX</PTiny>
|
|
424
|
-
</BadgeButton>
|
|
425
|
-
)}
|
|
426
|
-
</div>
|
|
427
|
-
</div>
|
|
428
|
-
)}
|
|
429
|
-
</CardBody>
|
|
430
|
-
</Card>
|
|
309
|
+
<TokenAmountCard
|
|
310
|
+
token={from}
|
|
311
|
+
isFiat={isFiat}
|
|
312
|
+
sender={sender}
|
|
313
|
+
amount={amountFrom}
|
|
314
|
+
readableAmount={String(showAmountFrom)}
|
|
315
|
+
readonlyAmount={setup?.readonlyAmount}
|
|
316
|
+
availableBalance={availableBalance}
|
|
317
|
+
isReviewing={isReviewing && type === "exactOut"}
|
|
318
|
+
setValue={setValue}
|
|
319
|
+
setIsFiat={setIsFiat}
|
|
320
|
+
setSender={setSender}
|
|
321
|
+
handleMax={handleMax}
|
|
322
|
+
setToken={setFrom}
|
|
323
|
+
kit={kit}
|
|
324
|
+
/>
|
|
431
325
|
|
|
432
326
|
<div style={{ position: "relative", height: 1, width: "100%" }}>
|
|
433
327
|
<SwitchButton
|
|
@@ -446,7 +340,7 @@ export const Bridge = observer(({ kit, widget, setup, onClose, onProcess, onStat
|
|
|
446
340
|
|
|
447
341
|
<Card style={{ borderRadius: "2px 2px 20px 20px" }}>
|
|
448
342
|
<CardHeader>
|
|
449
|
-
<ChainButton onClick={() => openSelectTokenPopup({ kit, onSelect: (token, wallet) => (setTo(token), setRecipient(wallet)) })}>
|
|
343
|
+
<ChainButton onClick={() => kit.router.openSelectTokenPopup({ kit, onSelect: (token, wallet) => (setTo(token), setRecipient(wallet)) })}>
|
|
450
344
|
<PSmall>To</PSmall>
|
|
451
345
|
<ImageView src={chains.get(to.chain)?.logo || ""} alt={to.symbol} size={16} />
|
|
452
346
|
<PSmall>{chains.get(to.chain)?.name}</PSmall>
|
|
@@ -455,7 +349,7 @@ export const Bridge = observer(({ kit, widget, setup, onClose, onProcess, onStat
|
|
|
455
349
|
|
|
456
350
|
<div style={{ display: "flex", alignItems: "center", gap: 8 }}>
|
|
457
351
|
<PSmall>Recipient:</PSmall>
|
|
458
|
-
<BadgeButton onClick={() => openSelectRecipient({ kit, chain: to.chain, onSelect: (recipient) => setRecipient(recipient) })}>
|
|
352
|
+
<BadgeButton onClick={() => kit.router.openSelectRecipient({ kit, chain: to.chain, onSelect: (recipient) => setRecipient(recipient) })}>
|
|
459
353
|
<PSmall>{recipient == null ? "Select" : formatter.truncateAddress(recipient.address, 8)}</PSmall>
|
|
460
354
|
<Tooltip id="recipient-tooltip">
|
|
461
355
|
<PSmall>Select recipient wallet</PSmall>
|
|
@@ -469,7 +363,7 @@ export const Bridge = observer(({ kit, widget, setup, onClose, onProcess, onStat
|
|
|
469
363
|
<TokenPreview
|
|
470
364
|
token={to}
|
|
471
365
|
onSelect={() =>
|
|
472
|
-
openSelectTokenPopup({
|
|
366
|
+
kit.router.openSelectTokenPopup({
|
|
473
367
|
kit,
|
|
474
368
|
initialChain: to.chain,
|
|
475
369
|
onSelect: (token, wallet) => {
|
|
@@ -511,16 +405,6 @@ export const Bridge = observer(({ kit, widget, setup, onClose, onProcess, onStat
|
|
|
511
405
|
);
|
|
512
406
|
});
|
|
513
407
|
|
|
514
|
-
const TokenPreview = ({ style, token, onSelect }: { style?: React.CSSProperties; token: Token; onSelect: (token: Token) => void }) => {
|
|
515
|
-
return (
|
|
516
|
-
<SelectTokenButton style={style} onClick={() => onSelect(token)}>
|
|
517
|
-
<TokenIcon withoutChain token={token} size={32} />
|
|
518
|
-
<PLarge>{token.symbol}</PLarge>
|
|
519
|
-
<ArrowRightIcon style={{ flexShrink: 0, position: "absolute", right: 4 }} />
|
|
520
|
-
</SelectTokenButton>
|
|
521
|
-
);
|
|
522
|
-
};
|
|
523
|
-
|
|
524
408
|
const TextField = styled(PTiny)`
|
|
525
409
|
max-width: 100%;
|
|
526
410
|
min-width: 300px;
|
|
@@ -536,172 +420,6 @@ const TextField = styled(PTiny)`
|
|
|
536
420
|
line-break: anywhere;
|
|
537
421
|
`;
|
|
538
422
|
|
|
539
|
-
const Tooltip = styled.div`
|
|
540
|
-
transition: 0.2s transform, 0.2s opacity;
|
|
541
|
-
transform: translateY(8px);
|
|
542
|
-
opacity: 0;
|
|
543
|
-
position: absolute;
|
|
544
|
-
top: -48px;
|
|
545
|
-
right: 0;
|
|
546
|
-
z-index: 100000000;
|
|
547
|
-
border-radius: 16px;
|
|
548
|
-
background: var(--surface-white, #fff);
|
|
549
|
-
padding: 4px 12px;
|
|
550
|
-
justify-content: center;
|
|
551
|
-
pointer-events: none;
|
|
552
|
-
align-items: center;
|
|
553
|
-
gap: 4px;
|
|
554
|
-
|
|
555
|
-
p {
|
|
556
|
-
white-space: nowrap;
|
|
557
|
-
color: #000;
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
&::after {
|
|
561
|
-
content: "";
|
|
562
|
-
position: absolute;
|
|
563
|
-
top: 100%;
|
|
564
|
-
right: 8px;
|
|
565
|
-
transform: translateX(-50%);
|
|
566
|
-
width: 0;
|
|
567
|
-
height: 0;
|
|
568
|
-
border-left: 8px solid transparent;
|
|
569
|
-
border-right: 8px solid transparent;
|
|
570
|
-
border-top: 8px solid #fff;
|
|
571
|
-
}
|
|
572
|
-
`;
|
|
573
|
-
|
|
574
|
-
const BadgeButton = styled.button`
|
|
575
|
-
display: flex;
|
|
576
|
-
border-radius: 8px;
|
|
577
|
-
border: 1px solid #323232;
|
|
578
|
-
padding: 4px 8px;
|
|
579
|
-
background: transparent;
|
|
580
|
-
transition: 0.2s border-color;
|
|
581
|
-
position: relative;
|
|
582
|
-
cursor: pointer;
|
|
583
|
-
outline: none;
|
|
584
|
-
gap: 4px;
|
|
585
|
-
|
|
586
|
-
&:hover {
|
|
587
|
-
border-color: #4e4e4e;
|
|
588
|
-
}
|
|
589
|
-
`;
|
|
590
|
-
|
|
591
|
-
const ChainButton = styled.button`
|
|
592
|
-
display: flex;
|
|
593
|
-
align-items: center;
|
|
594
|
-
padding: 0;
|
|
595
|
-
gap: 8px;
|
|
596
|
-
flex-shrink: 0;
|
|
597
|
-
cursor: pointer;
|
|
598
|
-
outline: none;
|
|
599
|
-
border: none;
|
|
600
|
-
background: transparent;
|
|
601
|
-
transition: 0.2s opacity;
|
|
602
|
-
|
|
603
|
-
&:hover {
|
|
604
|
-
opacity: 0.8;
|
|
605
|
-
}
|
|
606
|
-
`;
|
|
607
|
-
|
|
608
|
-
const SelectTokenButton = styled.button`
|
|
609
|
-
display: flex;
|
|
610
|
-
align-items: center;
|
|
611
|
-
gap: 8px;
|
|
612
|
-
flex-shrink: 0;
|
|
613
|
-
cursor: pointer;
|
|
614
|
-
outline: none;
|
|
615
|
-
border: none;
|
|
616
|
-
position: relative;
|
|
617
|
-
background: transparent;
|
|
618
|
-
border-radius: 24px;
|
|
619
|
-
padding: 4px;
|
|
620
|
-
padding-right: 28px;
|
|
621
|
-
margin: -4px;
|
|
622
|
-
max-width: 160px;
|
|
623
|
-
transition: 0.2s background-color;
|
|
624
|
-
|
|
625
|
-
&:hover {
|
|
626
|
-
background: rgba(255, 255, 255, 0.2);
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
p {
|
|
630
|
-
overflow: hidden;
|
|
631
|
-
text-overflow: ellipsis;
|
|
632
|
-
white-space: nowrap;
|
|
633
|
-
}
|
|
634
|
-
`;
|
|
635
|
-
|
|
636
|
-
const AvailableBalance = styled.div`
|
|
637
|
-
display: flex;
|
|
638
|
-
align-items: center;
|
|
639
|
-
overflow: hidden;
|
|
640
|
-
max-width: 200px;
|
|
641
|
-
white-space: nowrap;
|
|
642
|
-
gap: 4px;
|
|
643
|
-
|
|
644
|
-
p {
|
|
645
|
-
overflow: hidden;
|
|
646
|
-
text-overflow: ellipsis;
|
|
647
|
-
white-space: nowrap;
|
|
648
|
-
}
|
|
649
|
-
`;
|
|
650
|
-
|
|
651
|
-
const Card = styled.div`
|
|
652
|
-
text-align: left;
|
|
653
|
-
align-items: flex-start;
|
|
654
|
-
justify-content: center;
|
|
655
|
-
flex-direction: column;
|
|
656
|
-
|
|
657
|
-
display: flex;
|
|
658
|
-
width: 100%;
|
|
659
|
-
|
|
660
|
-
border-radius: 20px 20px 2px 2px;
|
|
661
|
-
border: 1px solid #323232;
|
|
662
|
-
background: #1f1f1f;
|
|
663
|
-
|
|
664
|
-
input {
|
|
665
|
-
outline: none;
|
|
666
|
-
border: none;
|
|
667
|
-
background: none;
|
|
668
|
-
color: #fff;
|
|
669
|
-
font-size: 32px;
|
|
670
|
-
font-weight: bold;
|
|
671
|
-
width: 100%;
|
|
672
|
-
line-height: 40px;
|
|
673
|
-
text-align: left;
|
|
674
|
-
align-items: flex-start;
|
|
675
|
-
justify-content: center;
|
|
676
|
-
background: transparent;
|
|
677
|
-
text-align: right;
|
|
678
|
-
border: none;
|
|
679
|
-
padding: 0;
|
|
680
|
-
margin: 0;
|
|
681
|
-
}
|
|
682
|
-
`;
|
|
683
|
-
|
|
684
|
-
const CardHeader = styled.div`
|
|
685
|
-
display: flex;
|
|
686
|
-
align-items: center;
|
|
687
|
-
justify-content: space-between;
|
|
688
|
-
padding: 8px 16px;
|
|
689
|
-
width: 100%;
|
|
690
|
-
gap: 8px;
|
|
691
|
-
`;
|
|
692
|
-
|
|
693
|
-
const CardBody = styled.div`
|
|
694
|
-
padding: 16px;
|
|
695
|
-
width: 100%;
|
|
696
|
-
flex-direction: column;
|
|
697
|
-
align-items: flex-start;
|
|
698
|
-
border-radius: 20px 20px 0 0;
|
|
699
|
-
border-top: 1px solid #323232;
|
|
700
|
-
background: #272727;
|
|
701
|
-
display: flex;
|
|
702
|
-
gap: 8px;
|
|
703
|
-
`;
|
|
704
|
-
|
|
705
423
|
const SwitchButton = styled.button`
|
|
706
424
|
position: absolute;
|
|
707
425
|
left: 50%;
|
|
@@ -13,15 +13,19 @@ import { ConnectorType, OmniConnector } from "../../core/OmniConnector";
|
|
|
13
13
|
import { OmniWallet } from "../../core/OmniWallet";
|
|
14
14
|
import { WalletType } from "../../core/chains";
|
|
15
15
|
import { formatter } from "../../core/utils";
|
|
16
|
+
import { PMedium, PSmall } from "../uikit/text";
|
|
17
|
+
import { WalletPicker } from "../connect/WalletPicker";
|
|
18
|
+
import { QRAnimation } from "../profile/DepositQR";
|
|
16
19
|
|
|
17
20
|
interface SelectSenderProps {
|
|
18
21
|
type: WalletType;
|
|
19
22
|
kit: HotKit;
|
|
23
|
+
disableQR?: boolean;
|
|
20
24
|
onClose: () => void;
|
|
21
25
|
onSelect: (wallet?: OmniWallet | "qr") => void;
|
|
22
26
|
}
|
|
23
27
|
|
|
24
|
-
export const SelectSender = observer(({ kit, type, onSelect, onClose }: SelectSenderProps) => {
|
|
28
|
+
export const SelectSender = observer(({ kit, type, disableQR, onSelect, onClose }: SelectSenderProps) => {
|
|
25
29
|
const connectors = kit.connectors.filter((t) => t.walletTypes.includes(type) && t.type !== ConnectorType.SOCIAL);
|
|
26
30
|
const noExternal = type === WalletType.OMNI || type === WalletType.COSMOS;
|
|
27
31
|
|
|
@@ -31,9 +35,27 @@ export const SelectSender = observer(({ kit, type, onSelect, onClose }: SelectSe
|
|
|
31
35
|
onClose();
|
|
32
36
|
};
|
|
33
37
|
|
|
38
|
+
if (connectors.length === 0 && (noExternal || disableQR)) {
|
|
39
|
+
return (
|
|
40
|
+
<Popup onClose={onClose} header={<p>Select sender</p>}>
|
|
41
|
+
<div style={{ width: "100%", height: 200, display: "flex", justifyContent: "center", alignItems: "center", flexDirection: "column", gap: 12 }}>
|
|
42
|
+
<PSmall>
|
|
43
|
+
No compatible wallets found,
|
|
44
|
+
<br />
|
|
45
|
+
try using flow for external wallets
|
|
46
|
+
</PSmall>
|
|
47
|
+
</div>
|
|
48
|
+
</Popup>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (connectors.length === 1 && (noExternal || disableQR)) {
|
|
53
|
+
return <WalletPicker initialConnector={connectors[0]} onSelect={onSelect} onClose={onClose} />;
|
|
54
|
+
}
|
|
55
|
+
|
|
34
56
|
return (
|
|
35
57
|
<Popup header={<p>Select sender</p>} onClose={onClose}>
|
|
36
|
-
{!noExternal && (
|
|
58
|
+
{!noExternal && !disableQR && (
|
|
37
59
|
<PopupOption onClick={() => (onSelect("qr"), onClose())}>
|
|
38
60
|
<div style={{ width: 44, height: 44, borderRadius: 16, background: "#000", display: "flex", alignItems: "center", justifyContent: "center" }}>
|
|
39
61
|
<QRIcon />
|
|
@@ -17,18 +17,27 @@ import { TokenCard } from "./TokenCard";
|
|
|
17
17
|
|
|
18
18
|
interface SelectTokenPopupProps {
|
|
19
19
|
kit: HotKit;
|
|
20
|
+
disableChains?: number[];
|
|
20
21
|
initialChain?: number;
|
|
21
22
|
onClose: () => void;
|
|
22
23
|
onSelect: (token: Token, wallet?: OmniWallet) => void;
|
|
23
24
|
}
|
|
24
25
|
|
|
25
|
-
export const SelectTokenPopup = observer(({ kit, initialChain, onClose, onSelect }: SelectTokenPopupProps) => {
|
|
26
|
+
export const SelectTokenPopup = observer(({ kit, disableChains, initialChain, onClose, onSelect }: SelectTokenPopupProps) => {
|
|
26
27
|
const [chain, setChain] = useState<number | null>(initialChain || null);
|
|
27
28
|
const [search, setSearch] = useState<string>("");
|
|
28
29
|
|
|
30
|
+
const availableTokens = tokens.list.filter((token) => !disableChains || !disableChains.includes(token.chain));
|
|
31
|
+
const selectChain = (chain: number) => {
|
|
32
|
+
setChain(chain);
|
|
33
|
+
setSearch("");
|
|
34
|
+
const tokens = availableTokens.filter((t) => t.chain === chain);
|
|
35
|
+
if (tokens.length === 1) onSelect(tokens[0]);
|
|
36
|
+
};
|
|
37
|
+
|
|
29
38
|
if (chain == null) {
|
|
30
39
|
const chains: Record<number, { chain: number; balance: number; name: string; icon: string }> = {};
|
|
31
|
-
|
|
40
|
+
availableTokens.forEach((token) => {
|
|
32
41
|
if (!chains[token.chain])
|
|
33
42
|
chains[token.chain] = {
|
|
34
43
|
chain: token.chain,
|
|
@@ -56,7 +65,7 @@ export const SelectTokenPopup = observer(({ kit, initialChain, onClose, onSelect
|
|
|
56
65
|
if (search && !name.toLowerCase().includes(search.toLowerCase())) return;
|
|
57
66
|
|
|
58
67
|
return (
|
|
59
|
-
<PopupOption onClick={() => (
|
|
68
|
+
<PopupOption onClick={() => selectChain(chain)}>
|
|
60
69
|
<ImageView src={icon} alt={name} size={24} />
|
|
61
70
|
<p style={{ fontSize: 24, fontWeight: "bold" }}>{name}</p>
|
|
62
71
|
{balance > 0 && <p style={{ marginLeft: "auto", fontSize: 20, color: "#c6c6c6" }}>${formatter.amount(balance)}</p>}
|
|
@@ -67,12 +76,12 @@ export const SelectTokenPopup = observer(({ kit, initialChain, onClose, onSelect
|
|
|
67
76
|
);
|
|
68
77
|
}
|
|
69
78
|
|
|
70
|
-
if (chain !==
|
|
79
|
+
if (chain !== Network.Omni && chain !== Network.HotCraft) {
|
|
71
80
|
return (
|
|
72
81
|
<Popup onClose={onClose} header={<p>Select token</p>} style={{ minHeight: 300 }}>
|
|
73
82
|
<SearchInput type="text" placeholder="Search token" onChange={(e) => setSearch(e.target.value)} />
|
|
74
83
|
|
|
75
|
-
{
|
|
84
|
+
{availableTokens
|
|
76
85
|
.filter((token) => token.chain === chain && token.symbol.toLowerCase().includes(search.toLowerCase()))
|
|
77
86
|
.sort((a, b) => {
|
|
78
87
|
const wallet = kit.wallets.find((w) => w.type === a.type)!;
|
|
@@ -95,7 +104,7 @@ export const SelectTokenPopup = observer(({ kit, initialChain, onClose, onSelect
|
|
|
95
104
|
<SearchInput type="text" placeholder="Search token" onChange={(e) => setSearch(e.target.value)} />
|
|
96
105
|
{kit.walletsTokens
|
|
97
106
|
.filter(({ token, balance }) => {
|
|
98
|
-
if (token.chain !==
|
|
107
|
+
if (token.chain !== chain) return false;
|
|
99
108
|
if (token.float(balance) < 0.0001) return false;
|
|
100
109
|
if (!token.symbol.toLowerCase().includes(search.toLowerCase())) return false;
|
|
101
110
|
used.add(token.address);
|