@hfunlabs/hypurr-connect 0.1.0 → 0.1.1
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/index.js +160 -29
- package/dist/index.js.map +1 -1
- package/package.json +13 -11
- package/src/HypurrConnectProvider.tsx +5 -1
- package/src/LoginModal.tsx +160 -26
- package/src/icons/MetaMaskColorIcon.tsx +5 -3
- package/src/icons/TelegramColorIcon.tsx +8 -6
package/dist/index.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
// src/HypurrConnectProvider.tsx
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
ExchangeClient,
|
|
4
|
+
HttpTransport,
|
|
5
|
+
InfoClient
|
|
6
|
+
} from "@hfunlabs/hyperliquid";
|
|
3
7
|
import { PrivateKeySigner } from "@hfunlabs/hyperliquid/signing";
|
|
4
8
|
import {
|
|
5
9
|
createContext,
|
|
@@ -454,18 +458,18 @@ import {
|
|
|
454
458
|
|
|
455
459
|
// src/icons/MetaMaskColorIcon.tsx
|
|
456
460
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
457
|
-
function MetaMaskColorIcon({
|
|
461
|
+
function MetaMaskColorIcon({ style }) {
|
|
458
462
|
return /* @__PURE__ */ jsxs(
|
|
459
463
|
"svg",
|
|
460
464
|
{
|
|
461
465
|
width: "24",
|
|
462
466
|
height: "24",
|
|
463
467
|
viewBox: "0 0 24 24",
|
|
464
|
-
|
|
468
|
+
style,
|
|
465
469
|
fill: "none",
|
|
466
470
|
xmlns: "http://www.w3.org/2000/svg",
|
|
467
471
|
children: [
|
|
468
|
-
/* @__PURE__ */ jsxs("g", {
|
|
472
|
+
/* @__PURE__ */ jsxs("g", { clipPath: "url(#clip0_2567_1088)", children: [
|
|
469
473
|
/* @__PURE__ */ jsx2(
|
|
470
474
|
"path",
|
|
471
475
|
{
|
|
@@ -532,14 +536,14 @@ function MetaMaskColorIcon({ className }) {
|
|
|
532
536
|
|
|
533
537
|
// src/icons/TelegramColorIcon.tsx
|
|
534
538
|
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
535
|
-
function TelegramColorIcon({
|
|
539
|
+
function TelegramColorIcon({ style }) {
|
|
536
540
|
return /* @__PURE__ */ jsxs2(
|
|
537
541
|
"svg",
|
|
538
542
|
{
|
|
539
543
|
width: "24",
|
|
540
544
|
height: "24",
|
|
541
545
|
viewBox: "0 0 24 24",
|
|
542
|
-
|
|
546
|
+
style,
|
|
543
547
|
fill: "none",
|
|
544
548
|
xmlns: "http://www.w3.org/2000/svg",
|
|
545
549
|
children: [
|
|
@@ -553,8 +557,8 @@ function TelegramColorIcon({ className }) {
|
|
|
553
557
|
/* @__PURE__ */ jsx3(
|
|
554
558
|
"path",
|
|
555
559
|
{
|
|
556
|
-
|
|
557
|
-
|
|
560
|
+
fillRule: "evenodd",
|
|
561
|
+
clipRule: "evenodd",
|
|
558
562
|
d: "M7.07426 11.905C9.69794 10.7619 11.4475 10.0083 12.3229 9.64417C14.8222 8.60458 15.3416 8.424 15.6801 8.41803C15.7546 8.41672 15.921 8.43517 16.0289 8.52267C16.1199 8.59655 16.145 8.69635 16.1569 8.7664C16.1689 8.83645 16.1839 8.99602 16.172 9.1207C16.0366 10.5438 15.4505 13.9973 15.1523 15.5912C15.0262 16.2657 14.7778 16.4918 14.5373 16.514C14.0146 16.562 13.6178 16.1686 13.1115 15.8367C12.3194 15.3175 11.8719 14.9943 11.103 14.4876C10.2145 13.902 10.7905 13.5802 11.2969 13.0542C11.4294 12.9166 13.7322 10.822 13.7768 10.632C13.7824 10.6082 13.7875 10.5196 13.7349 10.4729C13.6823 10.4261 13.6046 10.4421 13.5486 10.4548C13.4691 10.4728 12.2037 11.3092 9.75232 12.964C9.39313 13.2106 9.06779 13.3308 8.7763 13.3245C8.45496 13.3176 7.83681 13.1428 7.37729 12.9934C6.81366 12.8102 6.3657 12.7134 6.40471 12.4022C6.42503 12.2401 6.64821 12.0744 7.07426 11.905Z",
|
|
559
563
|
fill: "white"
|
|
560
564
|
}
|
|
@@ -569,8 +573,8 @@ function TelegramColorIcon({ className }) {
|
|
|
569
573
|
y2: "1789.65",
|
|
570
574
|
gradientUnits: "userSpaceOnUse",
|
|
571
575
|
children: [
|
|
572
|
-
/* @__PURE__ */ jsx3("stop", {
|
|
573
|
-
/* @__PURE__ */ jsx3("stop", { offset: "1",
|
|
576
|
+
/* @__PURE__ */ jsx3("stop", { stopColor: "#2AABEE" }),
|
|
577
|
+
/* @__PURE__ */ jsx3("stop", { offset: "1", stopColor: "#229ED9" })
|
|
574
578
|
]
|
|
575
579
|
}
|
|
576
580
|
) })
|
|
@@ -582,7 +586,67 @@ function TelegramColorIcon({ className }) {
|
|
|
582
586
|
// src/LoginModal.tsx
|
|
583
587
|
import { Fragment, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
584
588
|
var MOBILE_BREAKPOINT = 640;
|
|
585
|
-
var
|
|
589
|
+
var btnStyle = {
|
|
590
|
+
display: "flex",
|
|
591
|
+
height: 53,
|
|
592
|
+
width: "100%",
|
|
593
|
+
alignItems: "center",
|
|
594
|
+
gap: 12,
|
|
595
|
+
overflow: "hidden",
|
|
596
|
+
borderRadius: 6,
|
|
597
|
+
background: "rgba(255,255,255,0.05)",
|
|
598
|
+
padding: "0 24px",
|
|
599
|
+
fontSize: 14,
|
|
600
|
+
fontWeight: 600,
|
|
601
|
+
letterSpacing: "-0.01em",
|
|
602
|
+
color: "#fff",
|
|
603
|
+
cursor: "pointer",
|
|
604
|
+
border: "none",
|
|
605
|
+
transition: "background 150ms"
|
|
606
|
+
};
|
|
607
|
+
var btnHoverBg = { background: "rgba(255,255,255,0.1)" };
|
|
608
|
+
var backdropStyle = {
|
|
609
|
+
position: "fixed",
|
|
610
|
+
inset: 0,
|
|
611
|
+
zIndex: 100,
|
|
612
|
+
background: "rgba(0,0,0,0.6)",
|
|
613
|
+
backdropFilter: "blur(2px)",
|
|
614
|
+
WebkitBackdropFilter: "blur(2px)"
|
|
615
|
+
};
|
|
616
|
+
var modalWrapperStyle = {
|
|
617
|
+
position: "fixed",
|
|
618
|
+
inset: 0,
|
|
619
|
+
zIndex: 101,
|
|
620
|
+
display: "flex",
|
|
621
|
+
alignItems: "center",
|
|
622
|
+
justifyContent: "center",
|
|
623
|
+
padding: 16
|
|
624
|
+
};
|
|
625
|
+
var modalBoxStyle = {
|
|
626
|
+
display: "flex",
|
|
627
|
+
width: 400,
|
|
628
|
+
flexDirection: "column",
|
|
629
|
+
alignItems: "center",
|
|
630
|
+
gap: 16,
|
|
631
|
+
overflow: "hidden",
|
|
632
|
+
borderRadius: 12,
|
|
633
|
+
border: "1px solid rgba(255,255,255,0.1)",
|
|
634
|
+
background: "#282828",
|
|
635
|
+
padding: 24
|
|
636
|
+
};
|
|
637
|
+
var headingStyle = {
|
|
638
|
+
fontSize: 16,
|
|
639
|
+
fontWeight: 700,
|
|
640
|
+
letterSpacing: "-0.025em",
|
|
641
|
+
color: "#fff",
|
|
642
|
+
margin: 0
|
|
643
|
+
};
|
|
644
|
+
var dividerStyle = {
|
|
645
|
+
height: 1,
|
|
646
|
+
width: "100%",
|
|
647
|
+
background: "rgba(255,255,255,0.05)"
|
|
648
|
+
};
|
|
649
|
+
var iconSize = { width: 20, height: 20 };
|
|
586
650
|
var mobileQuery = typeof window !== "undefined" ? window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT}px)`) : null;
|
|
587
651
|
function subscribeMobile(cb) {
|
|
588
652
|
mobileQuery?.addEventListener("change", cb);
|
|
@@ -594,6 +658,21 @@ function getSnapshotMobile() {
|
|
|
594
658
|
function useIsMobile() {
|
|
595
659
|
return useSyncExternalStore(subscribeMobile, getSnapshotMobile, () => false);
|
|
596
660
|
}
|
|
661
|
+
function HoverButton({
|
|
662
|
+
onClick,
|
|
663
|
+
children
|
|
664
|
+
}) {
|
|
665
|
+
return /* @__PURE__ */ jsx4(
|
|
666
|
+
motion.button,
|
|
667
|
+
{
|
|
668
|
+
type: "button",
|
|
669
|
+
onClick,
|
|
670
|
+
style: btnStyle,
|
|
671
|
+
whileHover: btnHoverBg,
|
|
672
|
+
children
|
|
673
|
+
}
|
|
674
|
+
);
|
|
675
|
+
}
|
|
597
676
|
function LoginModal({ onConnectWallet, walletIcon }) {
|
|
598
677
|
const { loginTelegram, loginModalOpen, closeLoginModal, botId } = useHypurrConnect();
|
|
599
678
|
const handleTelegramAuth = useCallback2(
|
|
@@ -642,22 +721,33 @@ function LoginModal({ onConnectWallet, walletIcon }) {
|
|
|
642
721
|
}, [botId]);
|
|
643
722
|
const isMobile = useIsMobile();
|
|
644
723
|
const modalContent = /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
645
|
-
/* @__PURE__ */ jsx4(
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
724
|
+
/* @__PURE__ */ jsx4(
|
|
725
|
+
"div",
|
|
726
|
+
{
|
|
727
|
+
style: {
|
|
728
|
+
display: "flex",
|
|
729
|
+
width: "100%",
|
|
730
|
+
flexDirection: "column",
|
|
731
|
+
alignItems: "center",
|
|
732
|
+
gap: 8,
|
|
733
|
+
overflow: "hidden"
|
|
734
|
+
},
|
|
735
|
+
children: /* @__PURE__ */ jsxs3(HoverButton, { onClick: openTelegramOAuth, children: [
|
|
736
|
+
/* @__PURE__ */ jsx4(TelegramColorIcon, { style: iconSize }),
|
|
737
|
+
"Telegram"
|
|
738
|
+
] })
|
|
739
|
+
}
|
|
740
|
+
),
|
|
741
|
+
/* @__PURE__ */ jsx4("div", { style: dividerStyle }),
|
|
650
742
|
/* @__PURE__ */ jsxs3(
|
|
651
|
-
|
|
743
|
+
HoverButton,
|
|
652
744
|
{
|
|
653
|
-
type: "button",
|
|
654
745
|
onClick: () => {
|
|
655
746
|
closeLoginModal();
|
|
656
747
|
onConnectWallet();
|
|
657
748
|
},
|
|
658
|
-
className: btnClass,
|
|
659
749
|
children: [
|
|
660
|
-
walletIcon ?? /* @__PURE__ */ jsx4(MetaMaskColorIcon, {
|
|
750
|
+
walletIcon ?? /* @__PURE__ */ jsx4(MetaMaskColorIcon, { style: iconSize }),
|
|
661
751
|
"Wallet"
|
|
662
752
|
]
|
|
663
753
|
}
|
|
@@ -667,7 +757,7 @@ function LoginModal({ onConnectWallet, walletIcon }) {
|
|
|
667
757
|
/* @__PURE__ */ jsx4(
|
|
668
758
|
motion.div,
|
|
669
759
|
{
|
|
670
|
-
|
|
760
|
+
style: backdropStyle,
|
|
671
761
|
initial: { opacity: 0 },
|
|
672
762
|
animate: { opacity: 1 },
|
|
673
763
|
exit: { opacity: 0 },
|
|
@@ -679,7 +769,7 @@ function LoginModal({ onConnectWallet, walletIcon }) {
|
|
|
679
769
|
/* @__PURE__ */ jsx4(
|
|
680
770
|
motion.div,
|
|
681
771
|
{
|
|
682
|
-
|
|
772
|
+
style: modalWrapperStyle,
|
|
683
773
|
initial: { opacity: 0 },
|
|
684
774
|
animate: { opacity: 1 },
|
|
685
775
|
exit: { opacity: 0 },
|
|
@@ -688,14 +778,14 @@ function LoginModal({ onConnectWallet, walletIcon }) {
|
|
|
688
778
|
children: /* @__PURE__ */ jsxs3(
|
|
689
779
|
motion.div,
|
|
690
780
|
{
|
|
691
|
-
|
|
781
|
+
style: modalBoxStyle,
|
|
692
782
|
initial: { opacity: 0, scale: 0.95, y: 10 },
|
|
693
783
|
animate: { opacity: 1, scale: 1, y: 0 },
|
|
694
784
|
exit: { opacity: 0, scale: 0.95, y: 10 },
|
|
695
785
|
transition: { duration: 0.2, ease: "easeOut" },
|
|
696
786
|
onClick: (e) => e.stopPropagation(),
|
|
697
787
|
children: [
|
|
698
|
-
/* @__PURE__ */ jsx4("p", {
|
|
788
|
+
/* @__PURE__ */ jsx4("p", { style: headingStyle, children: "Connect" }),
|
|
699
789
|
modalContent
|
|
700
790
|
]
|
|
701
791
|
}
|
|
@@ -705,6 +795,47 @@ function LoginModal({ onConnectWallet, walletIcon }) {
|
|
|
705
795
|
)
|
|
706
796
|
] })) });
|
|
707
797
|
}
|
|
798
|
+
var drawerSheetStyle = {
|
|
799
|
+
position: "fixed",
|
|
800
|
+
left: 0,
|
|
801
|
+
right: 0,
|
|
802
|
+
bottom: 0,
|
|
803
|
+
zIndex: 101,
|
|
804
|
+
display: "flex",
|
|
805
|
+
flexDirection: "column",
|
|
806
|
+
alignItems: "center",
|
|
807
|
+
gap: 16,
|
|
808
|
+
borderTopLeftRadius: 12,
|
|
809
|
+
borderTopRightRadius: 12,
|
|
810
|
+
borderLeft: "1px solid rgba(255,255,255,0.1)",
|
|
811
|
+
borderRight: "1px solid rgba(255,255,255,0.1)",
|
|
812
|
+
borderTop: "1px solid rgba(255,255,255,0.1)",
|
|
813
|
+
background: "#282828",
|
|
814
|
+
padding: "12px 24px max(24px, env(safe-area-inset-bottom))"
|
|
815
|
+
};
|
|
816
|
+
var drawerBgStyle = {
|
|
817
|
+
position: "absolute",
|
|
818
|
+
left: 0,
|
|
819
|
+
right: 0,
|
|
820
|
+
top: 0,
|
|
821
|
+
bottom: "-100vh",
|
|
822
|
+
zIndex: -1,
|
|
823
|
+
background: "#282828",
|
|
824
|
+
borderTopLeftRadius: 12,
|
|
825
|
+
borderTopRightRadius: 12
|
|
826
|
+
};
|
|
827
|
+
var grabHandleAreaStyle = {
|
|
828
|
+
width: "100%",
|
|
829
|
+
cursor: "grab",
|
|
830
|
+
paddingBottom: 4
|
|
831
|
+
};
|
|
832
|
+
var grabHandleStyle = {
|
|
833
|
+
margin: "0 auto",
|
|
834
|
+
height: 4,
|
|
835
|
+
width: 100,
|
|
836
|
+
borderRadius: 9999,
|
|
837
|
+
background: "rgba(255,255,255,0.05)"
|
|
838
|
+
};
|
|
708
839
|
function MobileDrawer({
|
|
709
840
|
children,
|
|
710
841
|
onClose
|
|
@@ -724,7 +855,7 @@ function MobileDrawer({
|
|
|
724
855
|
/* @__PURE__ */ jsx4(
|
|
725
856
|
motion.div,
|
|
726
857
|
{
|
|
727
|
-
|
|
858
|
+
style: backdropStyle,
|
|
728
859
|
initial: { opacity: 0 },
|
|
729
860
|
animate: { opacity: 1 },
|
|
730
861
|
exit: { opacity: 0 },
|
|
@@ -736,7 +867,7 @@ function MobileDrawer({
|
|
|
736
867
|
/* @__PURE__ */ jsxs3(
|
|
737
868
|
motion.div,
|
|
738
869
|
{
|
|
739
|
-
|
|
870
|
+
style: drawerSheetStyle,
|
|
740
871
|
initial: { y: "100%" },
|
|
741
872
|
animate: { y: 0 },
|
|
742
873
|
exit: { y: "100%" },
|
|
@@ -746,9 +877,9 @@ function MobileDrawer({
|
|
|
746
877
|
dragElastic: { top: 0, bottom: 0.4 },
|
|
747
878
|
onDragEnd: handleDragEnd,
|
|
748
879
|
children: [
|
|
749
|
-
/* @__PURE__ */ jsx4("div", {
|
|
750
|
-
/* @__PURE__ */ jsx4("div", {
|
|
751
|
-
/* @__PURE__ */ jsx4("p", {
|
|
880
|
+
/* @__PURE__ */ jsx4("div", { style: drawerBgStyle }),
|
|
881
|
+
/* @__PURE__ */ jsx4("div", { style: grabHandleAreaStyle, children: /* @__PURE__ */ jsx4("div", { style: grabHandleStyle }) }),
|
|
882
|
+
/* @__PURE__ */ jsx4("p", { style: headingStyle, children: "Connect" }),
|
|
752
883
|
children
|
|
753
884
|
]
|
|
754
885
|
},
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/HypurrConnectProvider.tsx","../src/agent.ts","../src/grpc.ts","../src/GrpcExchangeTransport.ts","../src/LoginModal.tsx","../src/icons/MetaMaskColorIcon.tsx","../src/icons/TelegramColorIcon.tsx"],"sourcesContent":["import { ExchangeClient, HttpTransport, InfoClient } from \"@hfunlabs/hyperliquid\";\nimport { PrivateKeySigner } from \"@hfunlabs/hyperliquid/signing\";\nimport type { TelegramUserResponse } from \"hypurr-grpc/ts/hypurr/telegram/telegram_service\";\nimport type { TelegramUser as HypurrTelegramUser } from \"hypurr-grpc/ts/hypurr/user\";\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n type ReactNode,\n} from \"react\";\nimport {\n clearAgent as clearStoredAgent,\n generateAgentKey,\n loadAgent,\n saveAgent,\n} from \"./agent\";\nimport { createStaticClient, createTelegramClient } from \"./grpc\";\nimport { GrpcExchangeTransport } from \"./GrpcExchangeTransport\";\nimport type {\n AuthMethod,\n HypurrConnectConfig,\n HypurrConnectState,\n HypurrUser,\n SignTypedDataFn,\n StoredAgent,\n TelegramLoginData,\n} from \"./types\";\n\nconst TELEGRAM_STORAGE_KEY = \"hypurr-connect-tg-user\";\n\nfunction toAuthDataMap(data: TelegramLoginData): Record<string, string> {\n const map: Record<string, string> = {\n id: String(data.id),\n first_name: data.first_name,\n auth_date: String(data.auth_date),\n hash: data.hash,\n };\n if (data.last_name) map.last_name = data.last_name;\n if (data.username) map.username = data.username;\n if (data.photo_url) map.photo_url = data.photo_url;\n return map;\n}\n\nconst HypurrConnectContext = createContext<HypurrConnectState | null>(null);\n\nexport function useHypurrConnect(): HypurrConnectState {\n const ctx = useContext(HypurrConnectContext);\n if (!ctx)\n throw new Error(\n \"useHypurrConnect must be used within <HypurrConnectProvider>\",\n );\n return ctx;\n}\n\nexport function HypurrConnectProvider({\n config,\n children,\n}: {\n config: HypurrConnectConfig;\n children: ReactNode;\n}) {\n const tgClient = useMemo(() => createTelegramClient(config), [config]);\n const staticClient = useMemo(() => createStaticClient(config), [config]);\n\n // ── Telegram auth state ──────────────────────────────────────\n const [tgLoginData, setTgLoginData] = useState<TelegramLoginData | null>(\n () => {\n try {\n const stored = localStorage.getItem(TELEGRAM_STORAGE_KEY);\n return stored ? JSON.parse(stored) : null;\n } catch {\n return null;\n }\n },\n );\n const [tgUser, setTgUser] = useState<HypurrTelegramUser | null>(null);\n const [tgLoading, setTgLoading] = useState(false);\n const [tgError, setTgError] = useState<string | null>(null);\n\n const authDataMap = useMemo(\n () => (tgLoginData ? toAuthDataMap(tgLoginData) : {}),\n [tgLoginData],\n );\n\n useEffect(() => {\n if (!tgLoginData) return;\n let cancelled = false;\n setTgLoading(true);\n setTgError(null);\n\n (async () => {\n try {\n const authData = toAuthDataMap(tgLoginData);\n console.log(authData);\n const { response } = await tgClient.telegramUser({ authData });\n console.log(response);\n if (cancelled) return;\n setTgUser((response as TelegramUserResponse).user ?? null);\n } catch (err) {\n if (cancelled) return;\n console.error(\"[HypurrConnect] gRPC TelegramUser failed:\", err);\n setTgError(err instanceof Error ? err.message : String(err));\n } finally {\n if (!cancelled) setTgLoading(false);\n }\n })();\n\n return () => {\n cancelled = true;\n };\n }, [tgLoginData, tgClient]);\n\n // ── EOA auth state ───────────────────────────────────────────\n const [eoaAddress, setEoaAddress] = useState<`0x${string}` | null>(null);\n const [agent, setAgent] = useState<StoredAgent | null>(null);\n\n useEffect(() => {\n if (eoaAddress) {\n setAgent(loadAgent(eoaAddress));\n } else {\n setAgent(null);\n }\n }, [eoaAddress]);\n\n // ── Derived auth ─────────────────────────────────────────────\n const authMethod: AuthMethod = tgLoginData\n ? \"telegram\"\n : eoaAddress\n ? \"eoa\"\n : null;\n\n const tgWallet = tgUser?.wallet ?? (tgUser?.wallets ?? [])[0] ?? null;\n\n const user = useMemo<HypurrUser | null>(() => {\n if (tgLoginData && authMethod === \"telegram\") {\n return {\n address: tgWallet?.ethereumAddress ?? \"\",\n walletId: tgUser?.walletId ?? tgWallet?.id ?? 0,\n displayName: tgLoginData.username\n ? `@${tgLoginData.username}`\n : tgLoginData.first_name,\n photoUrl: tgLoginData.photo_url,\n authMethod: \"telegram\",\n telegramId: String(tgLoginData.id),\n };\n }\n if (eoaAddress && authMethod === \"eoa\") {\n return {\n address: eoaAddress,\n walletId: 0,\n displayName: `${eoaAddress.slice(0, 6)}...${eoaAddress.slice(-4)}`,\n authMethod: \"eoa\",\n };\n }\n return null;\n }, [tgLoginData, tgUser, tgWallet, eoaAddress, authMethod]);\n\n // ── Exchange client ──────────────────────────────────────────\n // Telegram: GrpcExchangeTransport → HyperliquidCoreAction (server signs)\n // EOA: HttpTransport + agent wallet (SDK signs locally)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const exchange = useMemo<ExchangeClient<any> | null>(() => {\n if (authMethod === \"telegram\" && user?.address) {\n const transport = new GrpcExchangeTransport({\n isTestnet: config.isTestnet ?? false,\n telegramClient: tgClient,\n authDataMap,\n walletId: user.walletId,\n });\n return new ExchangeClient({\n transport,\n externalSigning: true,\n userAddress: user.address as `0x${string}`,\n });\n }\n\n if (authMethod === \"eoa\" && agent) {\n const wallet = new PrivateKeySigner(agent.privateKey);\n return new ExchangeClient({\n transport: new HttpTransport({\n isTestnet: config.isTestnet ?? false,\n }),\n wallet,\n });\n }\n\n return null;\n }, [authMethod, user, agent, config.isTestnet, tgClient, authDataMap]);\n\n // ── USDC balance from Hyperliquid ──────────────────────────────\n const infoClient = useMemo(\n () =>\n new InfoClient({\n transport: new HttpTransport({\n isTestnet: config.isTestnet ?? false,\n }),\n }),\n [config.isTestnet],\n );\n\n const [usdcBalance, setUsdcBalance] = useState<string | null>(null);\n const [usdcBalanceLoading, setUsdcBalanceLoading] = useState(false);\n const [balanceTick, setBalanceTick] = useState(0);\n\n const refreshBalance = useCallback(() => setBalanceTick((t) => t + 1), []);\n\n useEffect(() => {\n const addr = user?.address;\n if (!addr) {\n setUsdcBalance(null);\n return;\n }\n\n let cancelled = false;\n setUsdcBalanceLoading(true);\n\n (async () => {\n try {\n const state = await infoClient.clearinghouseState({\n user: addr as `0x${string}`,\n });\n if (!cancelled) {\n setUsdcBalance(state.withdrawable);\n }\n } catch (err) {\n console.error(\"[HypurrConnect] Failed to fetch USDC balance:\", err);\n if (!cancelled) setUsdcBalance(null);\n } finally {\n if (!cancelled) setUsdcBalanceLoading(false);\n }\n })();\n\n return () => {\n cancelled = true;\n };\n }, [user?.address, infoClient, balanceTick]);\n\n // ── Agent approval (EOA flow) ────────────────────────────────\n const approveAgent = useCallback(\n async (signTypedDataAsync: SignTypedDataFn) => {\n if (!eoaAddress) throw new Error(\"No EOA address connected\");\n\n const { privateKey, address: agentAddress } = await generateAgentKey();\n\n const isTestnet = config.isTestnet ?? false;\n const nonce = Date.now();\n const action = {\n type: \"approveAgent\",\n signatureChainId: isTestnet ? \"0x66eee\" : \"0xa4b1\",\n hyperliquidChain: isTestnet ? \"Testnet\" : \"Mainnet\",\n agentAddress: agentAddress.toLowerCase() as `0x${string}`,\n agentName: null as string | null,\n nonce,\n };\n const types = {\n \"HyperliquidTransaction:ApproveAgent\": [\n { name: \"hyperliquidChain\", type: \"string\" },\n { name: \"agentAddress\", type: \"address\" },\n { name: \"agentName\", type: \"string\" },\n { name: \"nonce\", type: \"uint64\" },\n ],\n };\n\n const signature = await signTypedDataAsync({\n domain: {\n name: \"HyperliquidSignTransaction\",\n version: \"1\",\n chainId: isTestnet ? 421614 : 42161,\n verifyingContract: \"0x0000000000000000000000000000000000000000\",\n },\n types,\n primaryType: \"HyperliquidTransaction:ApproveAgent\",\n message: {\n hyperliquidChain: action.hyperliquidChain,\n agentAddress: action.agentAddress,\n agentName: \"\",\n nonce: BigInt(nonce),\n },\n });\n\n const r = `0x${signature.slice(2, 66)}`;\n const s = `0x${signature.slice(66, 130)}`;\n const v = parseInt(signature.slice(130, 132), 16);\n\n const url = isTestnet\n ? \"https://api.hyperliquid-testnet.xyz/exchange\"\n : \"https://api.hyperliquid.xyz/exchange\";\n\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n action,\n nonce,\n signature: { r, s, v },\n }),\n });\n\n const body = await res.json();\n if (body?.status !== \"ok\") {\n throw new Error(`approveAgent failed: ${JSON.stringify(body)}`);\n }\n\n const stored: StoredAgent = {\n privateKey,\n address: agentAddress,\n approvedAt: Date.now(),\n };\n saveAgent(eoaAddress, stored);\n setAgent(stored);\n },\n [eoaAddress, config.isTestnet],\n );\n\n const handleClearAgent = useCallback(() => {\n if (eoaAddress) {\n clearStoredAgent(eoaAddress);\n setAgent(null);\n }\n }, [eoaAddress]);\n\n // ── Login modal state ────────────────────────────────────────\n const [loginModalOpen, setLoginModalOpen] = useState(false);\n const openLoginModal = useCallback(() => setLoginModalOpen(true), []);\n const closeLoginModal = useCallback(() => setLoginModalOpen(false), []);\n\n // ── Auth actions ─────────────────────────────────────────────\n const loginTelegram = useCallback((data: TelegramLoginData) => {\n setTgLoginData(data);\n localStorage.setItem(TELEGRAM_STORAGE_KEY, JSON.stringify(data));\n setEoaAddress(null);\n setAgent(null);\n }, []);\n\n const loginEoa = useCallback((address: `0x${string}`) => {\n setEoaAddress(address);\n setTgLoginData(null);\n setTgUser(null);\n setTgError(null);\n localStorage.removeItem(TELEGRAM_STORAGE_KEY);\n }, []);\n\n const logout = useCallback(() => {\n setTgLoginData(null);\n setTgUser(null);\n setTgError(null);\n setEoaAddress(null);\n setAgent(null);\n localStorage.removeItem(TELEGRAM_STORAGE_KEY);\n }, []);\n\n // ── Context value ────────────────────────────────────────────\n const value = useMemo<HypurrConnectState>(\n () => ({\n user,\n isLoggedIn: !!user,\n isLoading: tgLoading,\n error: tgError,\n authMethod,\n exchange,\n\n usdcBalance,\n usdcBalanceLoading,\n refreshBalance,\n\n loginModalOpen,\n openLoginModal,\n closeLoginModal,\n\n loginTelegram,\n loginEoa,\n logout,\n\n agent,\n agentReady: authMethod === \"telegram\" || !!agent,\n approveAgent,\n clearAgent: handleClearAgent,\n\n botId: config.telegram?.botId ?? \"\",\n\n authDataMap,\n telegramClient: tgClient,\n staticClient,\n }),\n [\n user,\n tgLoading,\n tgError,\n authMethod,\n exchange,\n usdcBalance,\n usdcBalanceLoading,\n refreshBalance,\n loginModalOpen,\n openLoginModal,\n closeLoginModal,\n loginTelegram,\n loginEoa,\n logout,\n agent,\n approveAgent,\n handleClearAgent,\n config.telegram?.botId,\n authDataMap,\n tgClient,\n staticClient,\n ],\n );\n\n return (\n <HypurrConnectContext.Provider value={value}>\n {children}\n </HypurrConnectContext.Provider>\n );\n}\n","import type { StoredAgent } from \"./types\";\n\nconst AGENT_STORAGE_PREFIX = \"hypurr-connect-agent\";\n\nfunction storageKey(masterAddress: string): string {\n return `${AGENT_STORAGE_PREFIX}:${masterAddress.toLowerCase()}`;\n}\n\nexport function loadAgent(masterAddress: string): StoredAgent | null {\n try {\n const raw = localStorage.getItem(storageKey(masterAddress));\n return raw ? JSON.parse(raw) : null;\n } catch {\n return null;\n }\n}\n\nexport function saveAgent(masterAddress: string, agent: StoredAgent): void {\n localStorage.setItem(storageKey(masterAddress), JSON.stringify(agent));\n}\n\nexport function clearAgent(masterAddress: string): void {\n localStorage.removeItem(storageKey(masterAddress));\n}\n\n/**\n * Generate a random 32-byte private key and derive its address using the\n * SDK's PrivateKeySigner (no viem dependency needed).\n */\nexport async function generateAgentKey(): Promise<{\n privateKey: `0x${string}`;\n address: `0x${string}`;\n}> {\n const bytes = crypto.getRandomValues(new Uint8Array(32));\n const hex = Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n const privateKey = `0x${hex}` as `0x${string}`;\n\n const { PrivateKeySigner } = await import(\"@hfunlabs/hyperliquid/signing\");\n const signer = new PrivateKeySigner(privateKey);\n return { privateKey, address: signer.address };\n}\n","import { GrpcWebFetchTransport } from \"@protobuf-ts/grpcweb-transport\";\nimport { StaticClient } from \"hypurr-grpc/ts/hypurr/static/static_service.client\";\nimport { TelegramClient } from \"hypurr-grpc/ts/hypurr/telegram/telegram_service.client\";\nimport type { HypurrConnectConfig } from \"./types\";\n\nconst GRPC_URL = \"https://grpc.hypurr.fun\";\n\nfunction createTransport(config: HypurrConnectConfig) {\n return new GrpcWebFetchTransport({\n baseUrl: GRPC_URL,\n timeout: config.grpcTimeout ?? 15_000,\n });\n}\n\nexport function createTelegramClient(\n config: HypurrConnectConfig,\n): TelegramClient {\n return new TelegramClient(createTransport(config));\n}\n\nexport function createStaticClient(config: HypurrConnectConfig): StaticClient {\n return new StaticClient(createTransport(config));\n}\n","import type { IRequestTransport } from \"@hfunlabs/hyperliquid\";\nimport type { TelegramClient } from \"hypurr-grpc/ts/hypurr/telegram/telegram_service.client\";\n\nexport interface GrpcExchangeTransportConfig {\n isTestnet?: boolean;\n telegramClient: TelegramClient;\n authDataMap: Record<string, string>;\n walletId: number;\n}\n\ninterface ExchangePayload {\n action: { type: string; [key: string]: unknown };\n nonce: number;\n signature?: { r: string; s: string; v: number };\n vaultAddress?: string | null;\n}\n\n/**\n * Routes exchange requests through the Hypurr gRPC backend (HyperliquidCoreAction)\n * for server-side signing. The backend handles signature generation.\n *\n * The SDK-generated nonce is forwarded; the action payload is JSON-encoded as bytes.\n * Info/explorer requests are proxied directly to the Hyperliquid HTTP API.\n */\nexport class GrpcExchangeTransport implements IRequestTransport {\n isTestnet: boolean;\n private telegramClient: TelegramClient;\n private authDataMap: Record<string, string>;\n private walletId: number;\n private infoUrl: string;\n\n constructor(config: GrpcExchangeTransportConfig) {\n this.isTestnet = config.isTestnet ?? false;\n this.telegramClient = config.telegramClient;\n this.authDataMap = config.authDataMap;\n this.walletId = config.walletId;\n this.infoUrl = this.isTestnet\n ? \"https://api.hyperliquid-testnet.xyz\"\n : \"https://api.hyperliquid.xyz\";\n }\n\n async request<T>(\n endpoint: \"info\" | \"exchange\" | \"explorer\",\n payload: unknown,\n signal?: AbortSignal,\n ): Promise<T> {\n if (endpoint === \"exchange\") {\n return this.exchangeViaGrpc<T>(payload as ExchangePayload, signal);\n }\n return this.directRequest<T>(endpoint, payload, signal);\n }\n\n private async exchangeViaGrpc<T>(\n payload: ExchangePayload,\n signal?: AbortSignal,\n ): Promise<T> {\n if (signal?.aborted) {\n throw new DOMException(\"Request aborted\", \"AbortError\");\n }\n\n const actionBytes = new TextEncoder().encode(\n JSON.stringify(payload.action),\n );\n\n console.debug(\"[GrpcExchangeTransport] sending action:\", payload.action);\n\n const { response } = await this.telegramClient.hyperliquidCoreAction({\n authData: this.authDataMap,\n walletId: this.walletId,\n action: actionBytes,\n nonce: payload.nonce || Date.now(),\n });\n\n if (signal?.aborted) {\n throw new DOMException(\"Request aborted\", \"AbortError\");\n }\n\n const { status, result, error } = response;\n\n console.debug(\n \"[GrpcExchangeTransport] gRPC status:\",\n status,\n \"error:\",\n error,\n );\n\n if (error) {\n throw new Error(`GrpcExchangeTransport: ${error}`);\n }\n\n // The backend's `result` contains the raw Hyperliquid API JSON response.\n // The SDK's assertSuccessResponse expects the same shape as the HTTP API,\n // e.g. { status: \"ok\", response: { type: \"order\", data: { statuses: [...] } } }\n if (result && result.length > 0) {\n const parsed = JSON.parse(new TextDecoder().decode(result));\n console.debug(\"[GrpcExchangeTransport] parsed result:\", parsed);\n return parsed as T;\n }\n\n // Fallback: return a minimal success shape if no result bytes\n return { status: \"ok\", response: status } as T;\n }\n\n private async directRequest<T>(\n endpoint: string,\n payload: unknown,\n signal?: AbortSignal,\n ): Promise<T> {\n const res = await fetch(`${this.infoUrl}/${endpoint}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(payload),\n signal,\n });\n\n if (!res.ok) {\n throw new Error(`HTTP ${res.status}: ${await res.text()}`);\n }\n\n return (await res.json()) as T;\n }\n}\n","import {\n AnimatePresence,\n motion,\n useAnimationControls,\n type PanInfo,\n} from \"framer-motion\";\nimport {\n useCallback,\n useEffect,\n useSyncExternalStore,\n type ReactNode,\n} from \"react\";\nimport { useHypurrConnect } from \"./HypurrConnectProvider\";\nimport { MetaMaskColorIcon } from \"./icons/MetaMaskColorIcon\";\nimport { TelegramColorIcon } from \"./icons/TelegramColorIcon\";\nimport type { TelegramLoginData } from \"./types\";\n\nexport interface LoginModalProps {\n onConnectWallet: () => void;\n walletIcon?: ReactNode;\n}\n\nconst MOBILE_BREAKPOINT = 640;\n\nconst btnClass =\n \"flex h-[53px] w-full items-center gap-3 overflow-hidden rounded bg-white/5 px-6 text-sm font-semibold tracking-tight text-white cursor-pointer transition-colors duration-150 hover:bg-white/10\";\n\nconst mobileQuery =\n typeof window !== \"undefined\"\n ? window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT}px)`)\n : null;\n\nfunction subscribeMobile(cb: () => void) {\n mobileQuery?.addEventListener(\"change\", cb);\n return () => mobileQuery?.removeEventListener(\"change\", cb);\n}\n\nfunction getSnapshotMobile() {\n return mobileQuery?.matches ?? false;\n}\n\nfunction useIsMobile() {\n return useSyncExternalStore(subscribeMobile, getSnapshotMobile, () => false);\n}\n\nexport function LoginModal({ onConnectWallet, walletIcon }: LoginModalProps) {\n const { loginTelegram, loginModalOpen, closeLoginModal, botId } =\n useHypurrConnect();\n\n const handleTelegramAuth = useCallback(\n (user: TelegramLoginData) => {\n loginTelegram(user);\n closeLoginModal();\n },\n [loginTelegram, closeLoginModal],\n );\n\n useEffect(() => {\n if (!loginModalOpen) return;\n function onMessage(e: MessageEvent) {\n if (e.origin !== \"https://oauth.telegram.org\") return;\n try {\n const data = typeof e.data === \"string\" ? JSON.parse(e.data) : e.data;\n if (data?.event === \"auth_result\" && data.result) {\n const r = data.result;\n handleTelegramAuth({\n id: r.id,\n first_name: r.first_name ?? \"\",\n last_name: r.last_name ?? undefined,\n username: r.username ?? undefined,\n photo_url: r.photo_url ?? undefined,\n auth_date: r.auth_date,\n hash: r.hash,\n });\n }\n } catch {\n /* ignore non-JSON */\n }\n }\n window.addEventListener(\"message\", onMessage);\n return () => window.removeEventListener(\"message\", onMessage);\n }, [loginModalOpen, handleTelegramAuth]);\n\n const openTelegramOAuth = useCallback(() => {\n const origin = encodeURIComponent(window.location.origin);\n const url = `https://oauth.telegram.org/auth?bot_id=${botId}&origin=${origin}&request_access=write`;\n const w = 550;\n const h = 470;\n const left = window.screenX + (window.outerWidth - w) / 2;\n const top = window.screenY + (window.outerHeight - h) / 2;\n window.open(\n url,\n \"telegram_auth\",\n `width=${w},height=${h},left=${left},top=${top}`,\n );\n }, [botId]);\n\n const isMobile = useIsMobile();\n\n const modalContent = (\n <>\n <div className=\"flex w-full flex-col items-center gap-2 overflow-hidden\">\n <button type=\"button\" onClick={openTelegramOAuth} className={btnClass}>\n <TelegramColorIcon className=\"size-5\" />\n Telegram\n </button>\n </div>\n\n <div className=\"h-px w-full bg-white/5\" />\n\n <button\n type=\"button\"\n onClick={() => {\n closeLoginModal();\n onConnectWallet();\n }}\n className={btnClass}\n >\n {walletIcon ?? <MetaMaskColorIcon className=\"size-5\" />}\n Wallet\n </button>\n </>\n );\n\n return (\n <AnimatePresence>\n {loginModalOpen &&\n (isMobile ? (\n <MobileDrawer key=\"drawer\" onClose={closeLoginModal}>\n {modalContent}\n </MobileDrawer>\n ) : (\n <>\n <motion.div\n key=\"backdrop\"\n className=\"fixed inset-0 z-[100] bg-black/60 backdrop-blur-[2px]\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.15 }}\n onClick={closeLoginModal}\n />\n <motion.div\n key=\"modal-wrapper\"\n className=\"fixed inset-0 z-[101] flex items-center justify-center p-4\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.05 }}\n onClick={closeLoginModal}\n >\n <motion.div\n className=\"flex w-[400px] flex-col items-center gap-4 overflow-hidden rounded-xl border border-white/10 bg-[#282828] p-6\"\n initial={{ opacity: 0, scale: 0.95, y: 10 }}\n animate={{ opacity: 1, scale: 1, y: 0 }}\n exit={{ opacity: 0, scale: 0.95, y: 10 }}\n transition={{ duration: 0.2, ease: \"easeOut\" }}\n onClick={(e) => e.stopPropagation()}\n >\n <p className=\"text-base font-bold tracking-tight text-white\">\n Connect\n </p>\n {modalContent}\n </motion.div>\n </motion.div>\n </>\n ))}\n </AnimatePresence>\n );\n}\n\nfunction MobileDrawer({\n children,\n onClose,\n}: {\n children: ReactNode;\n onClose: () => void;\n}) {\n const controls = useAnimationControls();\n\n const handleDragEnd = useCallback(\n (_: unknown, info: PanInfo) => {\n if (info.offset.y > 100 || info.velocity.y > 500) {\n onClose();\n } else {\n controls.start({ y: 0 });\n }\n },\n [onClose, controls],\n );\n\n return (\n <>\n <motion.div\n key=\"drawer-backdrop\"\n className=\"fixed inset-0 z-[100] bg-black/60 backdrop-blur-[2px]\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.15 }}\n onClick={onClose}\n />\n\n <motion.div\n key=\"drawer-sheet\"\n className=\"fixed inset-x-0 bottom-0 z-[101] flex flex-col items-center gap-4 rounded-t-xl border-x border-t border-white/10 bg-[#282828] px-6 pb-[max(24px,env(safe-area-inset-bottom))] pt-3\"\n initial={{ y: \"100%\" }}\n animate={{ y: 0 }}\n exit={{ y: \"100%\" }}\n transition={{ type: \"tween\", duration: 0.3, ease: [0.32, 0.72, 0, 1] }}\n drag=\"y\"\n dragConstraints={{ top: 0, bottom: 0 }}\n dragElastic={{ top: 0, bottom: 0.4 }}\n onDragEnd={handleDragEnd}\n >\n <div className=\"absolute inset-x-0 top-0 bottom-[-100vh] -z-10 bg-[#282828] rounded-t-xl\" />\n\n <div className=\"w-full cursor-grab pt-0 pb-1 active:cursor-grabbing\">\n <div className=\"mx-auto h-1 w-[100px] rounded-full bg-white/5\" />\n </div>\n\n <p className=\"text-base font-bold tracking-tight text-white\">\n Connect\n </p>\n\n {children}\n </motion.div>\n </>\n );\n}\n","export function MetaMaskColorIcon({ className }: { className?: string }) {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n className={className}\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <g clip-path=\"url(#clip0_2567_1088)\">\n <path\n d=\"M19.8188 19.418L15.9421 18.2871L13.0186 19.9994L10.9788 19.9985L8.05356 18.2871L4.17862 19.418L3 15.5193L4.17875 11.1924L3 7.5341L4.17875 3L10.2336 6.54437H13.7639L19.8188 3L20.9976 7.5341L19.8188 11.1924L20.9976 15.5193L19.8188 19.418Z\"\n fill=\"#FF5C16\"\n />\n <path\n d=\"M4.17969 3L10.2347 6.54685L9.99394 8.98101L4.17969 3ZM8.05476 15.5209L10.7189 17.5093L8.05476 18.2869V15.5209ZM10.5059 12.2335L9.99394 8.98275L6.71642 11.1934L6.71464 11.1925V11.1941L6.72479 13.4695L8.05387 12.2336L10.5059 12.2335ZM19.819 3L13.7641 6.54685L14.004 8.98101L19.819 3ZM15.9441 15.5209L13.2798 17.5093L15.9441 18.2869V15.5209ZM17.2833 11.194V11.1924L17.2825 11.1932L14.0049 8.98275L13.4929 12.2335H15.944L17.2739 13.4693L17.2833 11.194Z\"\n fill=\"#FF5C16\"\n />\n <path\n d=\"M8.05369 18.2867L4.17875 19.4177L3 15.5207H8.05369V18.2867ZM10.5049 12.2324L11.245 16.9321L10.2191 14.319L6.72296 13.4691L8.0528 12.2325L10.5049 12.2324ZM15.9438 18.2867L19.8188 19.4177L20.9976 15.5206H15.9438C15.9438 15.5207 15.9438 18.2867 15.9438 18.2867ZM13.4927 12.2324L12.7526 16.9321L13.7783 14.319L17.2748 13.4691L15.944 12.2325L13.4927 12.2324Z\"\n fill=\"#E34807\"\n />\n <path\n d=\"M3 15.5194L4.17875 11.1924H6.71358L6.72283 13.4686L10.2194 14.3185L11.2451 16.9315L10.7178 17.5069L8.05369 15.5185H3V15.5194ZM20.9976 15.5194L19.8188 11.1924H17.2839L17.2746 13.4686L13.7783 14.3185L12.7524 16.9315L13.2796 17.5069L15.9439 15.5185H20.9976V15.5194ZM13.7639 6.54443H10.2336L9.99389 8.97859L11.2453 16.9289H12.7526L14.0047 8.97859L13.7639 6.54443Z\"\n fill=\"#FF8D5D\"\n />\n <path\n d=\"M4.17875 3L3 7.5341L4.17875 11.1924H6.71358L9.99287 8.98114L4.17875 3ZM9.77231 13.1766H8.62399L7.9988 13.7771L10.2202 14.3166L9.77231 13.1757V13.1766ZM19.8188 3L20.9976 7.5341L19.8188 11.1924H17.2839L14.0047 8.98114L19.8188 3ZM14.2269 13.1766H15.3769L16.0021 13.7778L13.7782 14.3184L14.2269 13.1757V13.1766ZM13.0178 18.4484L13.2798 17.5086L12.7524 16.9332H11.244L10.7168 17.5086L10.9787 18.4484\"\n fill=\"#661800\"\n />\n <path\n d=\"M13.0173 18.4482V20.0001H10.9785V18.4482H13.0173Z\"\n fill=\"#C0C4CD\"\n />\n <path\n d=\"M8.05469 18.2854L10.9807 19.9994V18.4475L10.7187 17.5078L8.05469 18.2854ZM15.944 18.2854L13.0179 19.9994V18.4475L13.2799 17.5078L15.944 18.2854Z\"\n fill=\"#E7EBF6\"\n />\n </g>\n <defs>\n <clipPath id=\"clip0_2567_1088\">\n <rect\n width=\"18\"\n height=\"17\"\n fill=\"white\"\n transform=\"translate(3 3)\"\n />\n </clipPath>\n </defs>\n </svg>\n );\n}\n","export function TelegramColorIcon({ className }: { className?: string }) {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n className={className}\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21Z\"\n fill=\"url(#paint0_linear_2571_1084)\"\n />\n <path\n fill-rule=\"evenodd\"\n clip-rule=\"evenodd\"\n d=\"M7.07426 11.905C9.69794 10.7619 11.4475 10.0083 12.3229 9.64417C14.8222 8.60458 15.3416 8.424 15.6801 8.41803C15.7546 8.41672 15.921 8.43517 16.0289 8.52267C16.1199 8.59655 16.145 8.69635 16.1569 8.7664C16.1689 8.83645 16.1839 8.99602 16.172 9.1207C16.0366 10.5438 15.4505 13.9973 15.1523 15.5912C15.0262 16.2657 14.7778 16.4918 14.5373 16.514C14.0146 16.562 13.6178 16.1686 13.1115 15.8367C12.3194 15.3175 11.8719 14.9943 11.103 14.4876C10.2145 13.902 10.7905 13.5802 11.2969 13.0542C11.4294 12.9166 13.7322 10.822 13.7768 10.632C13.7824 10.6082 13.7875 10.5196 13.7349 10.4729C13.6823 10.4261 13.6046 10.4421 13.5486 10.4548C13.4691 10.4728 12.2037 11.3092 9.75232 12.964C9.39313 13.2106 9.06779 13.3308 8.7763 13.3245C8.45496 13.3176 7.83681 13.1428 7.37729 12.9934C6.81366 12.8102 6.3657 12.7134 6.40471 12.4022C6.42503 12.2401 6.64821 12.0744 7.07426 11.905Z\"\n fill=\"white\"\n />\n <defs>\n <linearGradient\n id=\"paint0_linear_2571_1084\"\n x1=\"903\"\n y1=\"3\"\n x2=\"903\"\n y2=\"1789.65\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stop-color=\"#2AABEE\" />\n <stop offset=\"1\" stop-color=\"#229ED9\" />\n </linearGradient>\n </defs>\n </svg>\n );\n}\n"],"mappings":"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","names":["PrivateKeySigner","useCallback","useEffect","jsx","jsx","jsxs","jsx","jsxs","useCallback","useEffect"]}
|
|
1
|
+
{"version":3,"sources":["../src/HypurrConnectProvider.tsx","../src/agent.ts","../src/grpc.ts","../src/GrpcExchangeTransport.ts","../src/LoginModal.tsx","../src/icons/MetaMaskColorIcon.tsx","../src/icons/TelegramColorIcon.tsx"],"sourcesContent":["import {\n ExchangeClient,\n HttpTransport,\n InfoClient,\n} from \"@hfunlabs/hyperliquid\";\nimport { PrivateKeySigner } from \"@hfunlabs/hyperliquid/signing\";\nimport type { TelegramUserResponse } from \"hypurr-grpc/ts/hypurr/telegram/telegram_service\";\nimport type { TelegramUser as HypurrTelegramUser } from \"hypurr-grpc/ts/hypurr/user\";\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n type ReactNode,\n} from \"react\";\nimport {\n clearAgent as clearStoredAgent,\n generateAgentKey,\n loadAgent,\n saveAgent,\n} from \"./agent\";\nimport { createStaticClient, createTelegramClient } from \"./grpc\";\nimport { GrpcExchangeTransport } from \"./GrpcExchangeTransport\";\nimport type {\n AuthMethod,\n HypurrConnectConfig,\n HypurrConnectState,\n HypurrUser,\n SignTypedDataFn,\n StoredAgent,\n TelegramLoginData,\n} from \"./types\";\n\nconst TELEGRAM_STORAGE_KEY = \"hypurr-connect-tg-user\";\n\nfunction toAuthDataMap(data: TelegramLoginData): Record<string, string> {\n const map: Record<string, string> = {\n id: String(data.id),\n first_name: data.first_name,\n auth_date: String(data.auth_date),\n hash: data.hash,\n };\n if (data.last_name) map.last_name = data.last_name;\n if (data.username) map.username = data.username;\n if (data.photo_url) map.photo_url = data.photo_url;\n return map;\n}\n\nconst HypurrConnectContext = createContext<HypurrConnectState | null>(null);\n\nexport function useHypurrConnect(): HypurrConnectState {\n const ctx = useContext(HypurrConnectContext);\n if (!ctx)\n throw new Error(\n \"useHypurrConnect must be used within <HypurrConnectProvider>\",\n );\n return ctx;\n}\n\nexport function HypurrConnectProvider({\n config,\n children,\n}: {\n config: HypurrConnectConfig;\n children: ReactNode;\n}) {\n const tgClient = useMemo(() => createTelegramClient(config), [config]);\n const staticClient = useMemo(() => createStaticClient(config), [config]);\n\n // ── Telegram auth state ──────────────────────────────────────\n const [tgLoginData, setTgLoginData] = useState<TelegramLoginData | null>(\n () => {\n try {\n const stored = localStorage.getItem(TELEGRAM_STORAGE_KEY);\n return stored ? JSON.parse(stored) : null;\n } catch {\n return null;\n }\n },\n );\n const [tgUser, setTgUser] = useState<HypurrTelegramUser | null>(null);\n const [tgLoading, setTgLoading] = useState(false);\n const [tgError, setTgError] = useState<string | null>(null);\n\n const authDataMap = useMemo(\n () => (tgLoginData ? toAuthDataMap(tgLoginData) : {}),\n [tgLoginData],\n );\n\n useEffect(() => {\n if (!tgLoginData) return;\n let cancelled = false;\n setTgLoading(true);\n setTgError(null);\n\n (async () => {\n try {\n const authData = toAuthDataMap(tgLoginData);\n console.log(authData);\n const { response } = await tgClient.telegramUser({ authData });\n console.log(response);\n if (cancelled) return;\n setTgUser((response as TelegramUserResponse).user ?? null);\n } catch (err) {\n if (cancelled) return;\n console.error(\"[HypurrConnect] gRPC TelegramUser failed:\", err);\n setTgError(err instanceof Error ? err.message : String(err));\n } finally {\n if (!cancelled) setTgLoading(false);\n }\n })();\n\n return () => {\n cancelled = true;\n };\n }, [tgLoginData, tgClient]);\n\n // ── EOA auth state ───────────────────────────────────────────\n const [eoaAddress, setEoaAddress] = useState<`0x${string}` | null>(null);\n const [agent, setAgent] = useState<StoredAgent | null>(null);\n\n useEffect(() => {\n if (eoaAddress) {\n setAgent(loadAgent(eoaAddress));\n } else {\n setAgent(null);\n }\n }, [eoaAddress]);\n\n // ── Derived auth ─────────────────────────────────────────────\n const authMethod: AuthMethod = tgLoginData\n ? \"telegram\"\n : eoaAddress\n ? \"eoa\"\n : null;\n\n const tgWallet = tgUser?.wallet ?? (tgUser?.wallets ?? [])[0] ?? null;\n\n const user = useMemo<HypurrUser | null>(() => {\n if (tgLoginData && authMethod === \"telegram\") {\n return {\n address: tgWallet?.ethereumAddress ?? \"\",\n walletId: tgUser?.walletId ?? tgWallet?.id ?? 0,\n displayName: tgLoginData.username\n ? `@${tgLoginData.username}`\n : tgLoginData.first_name,\n photoUrl: tgLoginData.photo_url,\n authMethod: \"telegram\",\n telegramId: String(tgLoginData.id),\n };\n }\n if (eoaAddress && authMethod === \"eoa\") {\n return {\n address: eoaAddress,\n walletId: 0,\n displayName: `${eoaAddress.slice(0, 6)}...${eoaAddress.slice(-4)}`,\n authMethod: \"eoa\",\n };\n }\n return null;\n }, [tgLoginData, tgUser, tgWallet, eoaAddress, authMethod]);\n\n // ── Exchange client ──────────────────────────────────────────\n // Telegram: GrpcExchangeTransport → HyperliquidCoreAction (server signs)\n // EOA: HttpTransport + agent wallet (SDK signs locally)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const exchange = useMemo<ExchangeClient<any> | null>(() => {\n if (authMethod === \"telegram\" && user?.address) {\n const transport = new GrpcExchangeTransport({\n isTestnet: config.isTestnet ?? false,\n telegramClient: tgClient,\n authDataMap,\n walletId: user.walletId,\n });\n return new ExchangeClient({\n transport,\n externalSigning: true,\n userAddress: user.address as `0x${string}`,\n });\n }\n\n if (authMethod === \"eoa\" && agent) {\n const wallet = new PrivateKeySigner(agent.privateKey);\n return new ExchangeClient({\n transport: new HttpTransport({\n isTestnet: config.isTestnet ?? false,\n }),\n wallet,\n });\n }\n\n return null;\n }, [authMethod, user, agent, config.isTestnet, tgClient, authDataMap]);\n\n // ── USDC balance from Hyperliquid ──────────────────────────────\n const infoClient = useMemo(\n () =>\n new InfoClient({\n transport: new HttpTransport({\n isTestnet: config.isTestnet ?? false,\n }),\n }),\n [config.isTestnet],\n );\n\n const [usdcBalance, setUsdcBalance] = useState<string | null>(null);\n const [usdcBalanceLoading, setUsdcBalanceLoading] = useState(false);\n const [balanceTick, setBalanceTick] = useState(0);\n\n const refreshBalance = useCallback(() => setBalanceTick((t) => t + 1), []);\n\n useEffect(() => {\n const addr = user?.address;\n if (!addr) {\n setUsdcBalance(null);\n return;\n }\n\n let cancelled = false;\n setUsdcBalanceLoading(true);\n\n (async () => {\n try {\n const state = await infoClient.clearinghouseState({\n user: addr as `0x${string}`,\n });\n if (!cancelled) {\n setUsdcBalance(state.withdrawable);\n }\n } catch (err) {\n console.error(\"[HypurrConnect] Failed to fetch USDC balance:\", err);\n if (!cancelled) setUsdcBalance(null);\n } finally {\n if (!cancelled) setUsdcBalanceLoading(false);\n }\n })();\n\n return () => {\n cancelled = true;\n };\n }, [user?.address, infoClient, balanceTick]);\n\n // ── Agent approval (EOA flow) ────────────────────────────────\n const approveAgent = useCallback(\n async (signTypedDataAsync: SignTypedDataFn) => {\n if (!eoaAddress) throw new Error(\"No EOA address connected\");\n\n const { privateKey, address: agentAddress } = await generateAgentKey();\n\n const isTestnet = config.isTestnet ?? false;\n const nonce = Date.now();\n const action = {\n type: \"approveAgent\",\n signatureChainId: isTestnet ? \"0x66eee\" : \"0xa4b1\",\n hyperliquidChain: isTestnet ? \"Testnet\" : \"Mainnet\",\n agentAddress: agentAddress.toLowerCase() as `0x${string}`,\n agentName: null as string | null,\n nonce,\n };\n const types = {\n \"HyperliquidTransaction:ApproveAgent\": [\n { name: \"hyperliquidChain\", type: \"string\" },\n { name: \"agentAddress\", type: \"address\" },\n { name: \"agentName\", type: \"string\" },\n { name: \"nonce\", type: \"uint64\" },\n ],\n };\n\n const signature = await signTypedDataAsync({\n domain: {\n name: \"HyperliquidSignTransaction\",\n version: \"1\",\n chainId: isTestnet ? 421614 : 42161,\n verifyingContract: \"0x0000000000000000000000000000000000000000\",\n },\n types,\n primaryType: \"HyperliquidTransaction:ApproveAgent\",\n message: {\n hyperliquidChain: action.hyperliquidChain,\n agentAddress: action.agentAddress,\n agentName: \"\",\n nonce: BigInt(nonce),\n },\n });\n\n const r = `0x${signature.slice(2, 66)}`;\n const s = `0x${signature.slice(66, 130)}`;\n const v = parseInt(signature.slice(130, 132), 16);\n\n const url = isTestnet\n ? \"https://api.hyperliquid-testnet.xyz/exchange\"\n : \"https://api.hyperliquid.xyz/exchange\";\n\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n action,\n nonce,\n signature: { r, s, v },\n }),\n });\n\n const body = await res.json();\n if (body?.status !== \"ok\") {\n throw new Error(`approveAgent failed: ${JSON.stringify(body)}`);\n }\n\n const stored: StoredAgent = {\n privateKey,\n address: agentAddress,\n approvedAt: Date.now(),\n };\n saveAgent(eoaAddress, stored);\n setAgent(stored);\n },\n [eoaAddress, config.isTestnet],\n );\n\n const handleClearAgent = useCallback(() => {\n if (eoaAddress) {\n clearStoredAgent(eoaAddress);\n setAgent(null);\n }\n }, [eoaAddress]);\n\n // ── Login modal state ────────────────────────────────────────\n const [loginModalOpen, setLoginModalOpen] = useState(false);\n const openLoginModal = useCallback(() => setLoginModalOpen(true), []);\n const closeLoginModal = useCallback(() => setLoginModalOpen(false), []);\n\n // ── Auth actions ─────────────────────────────────────────────\n const loginTelegram = useCallback((data: TelegramLoginData) => {\n setTgLoginData(data);\n localStorage.setItem(TELEGRAM_STORAGE_KEY, JSON.stringify(data));\n setEoaAddress(null);\n setAgent(null);\n }, []);\n\n const loginEoa = useCallback((address: `0x${string}`) => {\n setEoaAddress(address);\n setTgLoginData(null);\n setTgUser(null);\n setTgError(null);\n localStorage.removeItem(TELEGRAM_STORAGE_KEY);\n }, []);\n\n const logout = useCallback(() => {\n setTgLoginData(null);\n setTgUser(null);\n setTgError(null);\n setEoaAddress(null);\n setAgent(null);\n localStorage.removeItem(TELEGRAM_STORAGE_KEY);\n }, []);\n\n // ── Context value ────────────────────────────────────────────\n const value = useMemo<HypurrConnectState>(\n () => ({\n user,\n isLoggedIn: !!user,\n isLoading: tgLoading,\n error: tgError,\n authMethod,\n exchange,\n\n usdcBalance,\n usdcBalanceLoading,\n refreshBalance,\n\n loginModalOpen,\n openLoginModal,\n closeLoginModal,\n\n loginTelegram,\n loginEoa,\n logout,\n\n agent,\n agentReady: authMethod === \"telegram\" || !!agent,\n approveAgent,\n clearAgent: handleClearAgent,\n\n botId: config.telegram?.botId ?? \"\",\n\n authDataMap,\n telegramClient: tgClient,\n staticClient,\n }),\n [\n user,\n tgLoading,\n tgError,\n authMethod,\n exchange,\n usdcBalance,\n usdcBalanceLoading,\n refreshBalance,\n loginModalOpen,\n openLoginModal,\n closeLoginModal,\n loginTelegram,\n loginEoa,\n logout,\n agent,\n approveAgent,\n handleClearAgent,\n config.telegram?.botId,\n authDataMap,\n tgClient,\n staticClient,\n ],\n );\n\n return (\n <HypurrConnectContext.Provider value={value}>\n {children}\n </HypurrConnectContext.Provider>\n );\n}\n","import type { StoredAgent } from \"./types\";\n\nconst AGENT_STORAGE_PREFIX = \"hypurr-connect-agent\";\n\nfunction storageKey(masterAddress: string): string {\n return `${AGENT_STORAGE_PREFIX}:${masterAddress.toLowerCase()}`;\n}\n\nexport function loadAgent(masterAddress: string): StoredAgent | null {\n try {\n const raw = localStorage.getItem(storageKey(masterAddress));\n return raw ? JSON.parse(raw) : null;\n } catch {\n return null;\n }\n}\n\nexport function saveAgent(masterAddress: string, agent: StoredAgent): void {\n localStorage.setItem(storageKey(masterAddress), JSON.stringify(agent));\n}\n\nexport function clearAgent(masterAddress: string): void {\n localStorage.removeItem(storageKey(masterAddress));\n}\n\n/**\n * Generate a random 32-byte private key and derive its address using the\n * SDK's PrivateKeySigner (no viem dependency needed).\n */\nexport async function generateAgentKey(): Promise<{\n privateKey: `0x${string}`;\n address: `0x${string}`;\n}> {\n const bytes = crypto.getRandomValues(new Uint8Array(32));\n const hex = Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n const privateKey = `0x${hex}` as `0x${string}`;\n\n const { PrivateKeySigner } = await import(\"@hfunlabs/hyperliquid/signing\");\n const signer = new PrivateKeySigner(privateKey);\n return { privateKey, address: signer.address };\n}\n","import { GrpcWebFetchTransport } from \"@protobuf-ts/grpcweb-transport\";\nimport { StaticClient } from \"hypurr-grpc/ts/hypurr/static/static_service.client\";\nimport { TelegramClient } from \"hypurr-grpc/ts/hypurr/telegram/telegram_service.client\";\nimport type { HypurrConnectConfig } from \"./types\";\n\nconst GRPC_URL = \"https://grpc.hypurr.fun\";\n\nfunction createTransport(config: HypurrConnectConfig) {\n return new GrpcWebFetchTransport({\n baseUrl: GRPC_URL,\n timeout: config.grpcTimeout ?? 15_000,\n });\n}\n\nexport function createTelegramClient(\n config: HypurrConnectConfig,\n): TelegramClient {\n return new TelegramClient(createTransport(config));\n}\n\nexport function createStaticClient(config: HypurrConnectConfig): StaticClient {\n return new StaticClient(createTransport(config));\n}\n","import type { IRequestTransport } from \"@hfunlabs/hyperliquid\";\nimport type { TelegramClient } from \"hypurr-grpc/ts/hypurr/telegram/telegram_service.client\";\n\nexport interface GrpcExchangeTransportConfig {\n isTestnet?: boolean;\n telegramClient: TelegramClient;\n authDataMap: Record<string, string>;\n walletId: number;\n}\n\ninterface ExchangePayload {\n action: { type: string; [key: string]: unknown };\n nonce: number;\n signature?: { r: string; s: string; v: number };\n vaultAddress?: string | null;\n}\n\n/**\n * Routes exchange requests through the Hypurr gRPC backend (HyperliquidCoreAction)\n * for server-side signing. The backend handles signature generation.\n *\n * The SDK-generated nonce is forwarded; the action payload is JSON-encoded as bytes.\n * Info/explorer requests are proxied directly to the Hyperliquid HTTP API.\n */\nexport class GrpcExchangeTransport implements IRequestTransport {\n isTestnet: boolean;\n private telegramClient: TelegramClient;\n private authDataMap: Record<string, string>;\n private walletId: number;\n private infoUrl: string;\n\n constructor(config: GrpcExchangeTransportConfig) {\n this.isTestnet = config.isTestnet ?? false;\n this.telegramClient = config.telegramClient;\n this.authDataMap = config.authDataMap;\n this.walletId = config.walletId;\n this.infoUrl = this.isTestnet\n ? \"https://api.hyperliquid-testnet.xyz\"\n : \"https://api.hyperliquid.xyz\";\n }\n\n async request<T>(\n endpoint: \"info\" | \"exchange\" | \"explorer\",\n payload: unknown,\n signal?: AbortSignal,\n ): Promise<T> {\n if (endpoint === \"exchange\") {\n return this.exchangeViaGrpc<T>(payload as ExchangePayload, signal);\n }\n return this.directRequest<T>(endpoint, payload, signal);\n }\n\n private async exchangeViaGrpc<T>(\n payload: ExchangePayload,\n signal?: AbortSignal,\n ): Promise<T> {\n if (signal?.aborted) {\n throw new DOMException(\"Request aborted\", \"AbortError\");\n }\n\n const actionBytes = new TextEncoder().encode(\n JSON.stringify(payload.action),\n );\n\n console.debug(\"[GrpcExchangeTransport] sending action:\", payload.action);\n\n const { response } = await this.telegramClient.hyperliquidCoreAction({\n authData: this.authDataMap,\n walletId: this.walletId,\n action: actionBytes,\n nonce: payload.nonce || Date.now(),\n });\n\n if (signal?.aborted) {\n throw new DOMException(\"Request aborted\", \"AbortError\");\n }\n\n const { status, result, error } = response;\n\n console.debug(\n \"[GrpcExchangeTransport] gRPC status:\",\n status,\n \"error:\",\n error,\n );\n\n if (error) {\n throw new Error(`GrpcExchangeTransport: ${error}`);\n }\n\n // The backend's `result` contains the raw Hyperliquid API JSON response.\n // The SDK's assertSuccessResponse expects the same shape as the HTTP API,\n // e.g. { status: \"ok\", response: { type: \"order\", data: { statuses: [...] } } }\n if (result && result.length > 0) {\n const parsed = JSON.parse(new TextDecoder().decode(result));\n console.debug(\"[GrpcExchangeTransport] parsed result:\", parsed);\n return parsed as T;\n }\n\n // Fallback: return a minimal success shape if no result bytes\n return { status: \"ok\", response: status } as T;\n }\n\n private async directRequest<T>(\n endpoint: string,\n payload: unknown,\n signal?: AbortSignal,\n ): Promise<T> {\n const res = await fetch(`${this.infoUrl}/${endpoint}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(payload),\n signal,\n });\n\n if (!res.ok) {\n throw new Error(`HTTP ${res.status}: ${await res.text()}`);\n }\n\n return (await res.json()) as T;\n }\n}\n","import {\n AnimatePresence,\n motion,\n useAnimationControls,\n type PanInfo,\n} from \"framer-motion\";\nimport {\n useCallback,\n useEffect,\n useSyncExternalStore,\n type CSSProperties,\n type ReactNode,\n} from \"react\";\nimport { useHypurrConnect } from \"./HypurrConnectProvider\";\nimport { MetaMaskColorIcon } from \"./icons/MetaMaskColorIcon\";\nimport { TelegramColorIcon } from \"./icons/TelegramColorIcon\";\nimport type { TelegramLoginData } from \"./types\";\n\nexport interface LoginModalProps {\n onConnectWallet: () => void;\n walletIcon?: ReactNode;\n}\n\nconst MOBILE_BREAKPOINT = 640;\n\nconst btnStyle: CSSProperties = {\n display: \"flex\",\n height: 53,\n width: \"100%\",\n alignItems: \"center\",\n gap: 12,\n overflow: \"hidden\",\n borderRadius: 6,\n background: \"rgba(255,255,255,0.05)\",\n padding: \"0 24px\",\n fontSize: 14,\n fontWeight: 600,\n letterSpacing: \"-0.01em\",\n color: \"#fff\",\n cursor: \"pointer\",\n border: \"none\",\n transition: \"background 150ms\",\n};\n\nconst btnHoverBg = { background: \"rgba(255,255,255,0.1)\" };\n\nconst backdropStyle: CSSProperties = {\n position: \"fixed\",\n inset: 0,\n zIndex: 100,\n background: \"rgba(0,0,0,0.6)\",\n backdropFilter: \"blur(2px)\",\n WebkitBackdropFilter: \"blur(2px)\",\n};\n\nconst modalWrapperStyle: CSSProperties = {\n position: \"fixed\",\n inset: 0,\n zIndex: 101,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: 16,\n};\n\nconst modalBoxStyle: CSSProperties = {\n display: \"flex\",\n width: 400,\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: 16,\n overflow: \"hidden\",\n borderRadius: 12,\n border: \"1px solid rgba(255,255,255,0.1)\",\n background: \"#282828\",\n padding: 24,\n};\n\nconst headingStyle: CSSProperties = {\n fontSize: 16,\n fontWeight: 700,\n letterSpacing: \"-0.025em\",\n color: \"#fff\",\n margin: 0,\n};\n\nconst dividerStyle: CSSProperties = {\n height: 1,\n width: \"100%\",\n background: \"rgba(255,255,255,0.05)\",\n};\n\nconst iconSize: CSSProperties = { width: 20, height: 20 };\n\nconst mobileQuery =\n typeof window !== \"undefined\"\n ? window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT}px)`)\n : null;\n\nfunction subscribeMobile(cb: () => void) {\n mobileQuery?.addEventListener(\"change\", cb);\n return () => mobileQuery?.removeEventListener(\"change\", cb);\n}\n\nfunction getSnapshotMobile() {\n return mobileQuery?.matches ?? false;\n}\n\nfunction useIsMobile() {\n return useSyncExternalStore(subscribeMobile, getSnapshotMobile, () => false);\n}\n\nfunction HoverButton({\n onClick,\n children,\n}: {\n onClick: () => void;\n children: ReactNode;\n}) {\n return (\n <motion.button\n type=\"button\"\n onClick={onClick}\n style={btnStyle}\n whileHover={btnHoverBg}\n >\n {children}\n </motion.button>\n );\n}\n\nexport function LoginModal({ onConnectWallet, walletIcon }: LoginModalProps) {\n const { loginTelegram, loginModalOpen, closeLoginModal, botId } =\n useHypurrConnect();\n\n const handleTelegramAuth = useCallback(\n (user: TelegramLoginData) => {\n loginTelegram(user);\n closeLoginModal();\n },\n [loginTelegram, closeLoginModal],\n );\n\n useEffect(() => {\n if (!loginModalOpen) return;\n function onMessage(e: MessageEvent) {\n if (e.origin !== \"https://oauth.telegram.org\") return;\n try {\n const data = typeof e.data === \"string\" ? JSON.parse(e.data) : e.data;\n if (data?.event === \"auth_result\" && data.result) {\n const r = data.result;\n handleTelegramAuth({\n id: r.id,\n first_name: r.first_name ?? \"\",\n last_name: r.last_name ?? undefined,\n username: r.username ?? undefined,\n photo_url: r.photo_url ?? undefined,\n auth_date: r.auth_date,\n hash: r.hash,\n });\n }\n } catch {\n /* ignore non-JSON */\n }\n }\n window.addEventListener(\"message\", onMessage);\n return () => window.removeEventListener(\"message\", onMessage);\n }, [loginModalOpen, handleTelegramAuth]);\n\n const openTelegramOAuth = useCallback(() => {\n const origin = encodeURIComponent(window.location.origin);\n const url = `https://oauth.telegram.org/auth?bot_id=${botId}&origin=${origin}&request_access=write`;\n const w = 550;\n const h = 470;\n const left = window.screenX + (window.outerWidth - w) / 2;\n const top = window.screenY + (window.outerHeight - h) / 2;\n window.open(\n url,\n \"telegram_auth\",\n `width=${w},height=${h},left=${left},top=${top}`,\n );\n }, [botId]);\n\n const isMobile = useIsMobile();\n\n const modalContent = (\n <>\n <div\n style={{\n display: \"flex\",\n width: \"100%\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: 8,\n overflow: \"hidden\",\n }}\n >\n <HoverButton onClick={openTelegramOAuth}>\n <TelegramColorIcon style={iconSize} />\n Telegram\n </HoverButton>\n </div>\n\n <div style={dividerStyle} />\n\n <HoverButton\n onClick={() => {\n closeLoginModal();\n onConnectWallet();\n }}\n >\n {walletIcon ?? <MetaMaskColorIcon style={iconSize} />}\n Wallet\n </HoverButton>\n </>\n );\n\n return (\n <AnimatePresence>\n {loginModalOpen &&\n (isMobile ? (\n <MobileDrawer key=\"drawer\" onClose={closeLoginModal}>\n {modalContent}\n </MobileDrawer>\n ) : (\n <>\n <motion.div\n key=\"backdrop\"\n style={backdropStyle}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.15 }}\n onClick={closeLoginModal}\n />\n <motion.div\n key=\"modal-wrapper\"\n style={modalWrapperStyle}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.05 }}\n onClick={closeLoginModal}\n >\n <motion.div\n style={modalBoxStyle}\n initial={{ opacity: 0, scale: 0.95, y: 10 }}\n animate={{ opacity: 1, scale: 1, y: 0 }}\n exit={{ opacity: 0, scale: 0.95, y: 10 }}\n transition={{ duration: 0.2, ease: \"easeOut\" }}\n onClick={(e) => e.stopPropagation()}\n >\n <p style={headingStyle}>Connect</p>\n {modalContent}\n </motion.div>\n </motion.div>\n </>\n ))}\n </AnimatePresence>\n );\n}\n\nconst drawerSheetStyle: CSSProperties = {\n position: \"fixed\",\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 101,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: 16,\n borderTopLeftRadius: 12,\n borderTopRightRadius: 12,\n borderLeft: \"1px solid rgba(255,255,255,0.1)\",\n borderRight: \"1px solid rgba(255,255,255,0.1)\",\n borderTop: \"1px solid rgba(255,255,255,0.1)\",\n background: \"#282828\",\n padding: \"12px 24px max(24px, env(safe-area-inset-bottom))\",\n};\n\nconst drawerBgStyle: CSSProperties = {\n position: \"absolute\",\n left: 0,\n right: 0,\n top: 0,\n bottom: \"-100vh\",\n zIndex: -1,\n background: \"#282828\",\n borderTopLeftRadius: 12,\n borderTopRightRadius: 12,\n};\n\nconst grabHandleAreaStyle: CSSProperties = {\n width: \"100%\",\n cursor: \"grab\",\n paddingBottom: 4,\n};\n\nconst grabHandleStyle: CSSProperties = {\n margin: \"0 auto\",\n height: 4,\n width: 100,\n borderRadius: 9999,\n background: \"rgba(255,255,255,0.05)\",\n};\n\nfunction MobileDrawer({\n children,\n onClose,\n}: {\n children: ReactNode;\n onClose: () => void;\n}) {\n const controls = useAnimationControls();\n\n const handleDragEnd = useCallback(\n (_: unknown, info: PanInfo) => {\n if (info.offset.y > 100 || info.velocity.y > 500) {\n onClose();\n } else {\n controls.start({ y: 0 });\n }\n },\n [onClose, controls],\n );\n\n return (\n <>\n <motion.div\n key=\"drawer-backdrop\"\n style={backdropStyle}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.15 }}\n onClick={onClose}\n />\n\n <motion.div\n key=\"drawer-sheet\"\n style={drawerSheetStyle}\n initial={{ y: \"100%\" }}\n animate={{ y: 0 }}\n exit={{ y: \"100%\" }}\n transition={{ type: \"tween\", duration: 0.3, ease: [0.32, 0.72, 0, 1] }}\n drag=\"y\"\n dragConstraints={{ top: 0, bottom: 0 }}\n dragElastic={{ top: 0, bottom: 0.4 }}\n onDragEnd={handleDragEnd}\n >\n <div style={drawerBgStyle} />\n\n <div style={grabHandleAreaStyle}>\n <div style={grabHandleStyle} />\n </div>\n\n <p style={headingStyle}>Connect</p>\n\n {children}\n </motion.div>\n </>\n );\n}\n","import type { CSSProperties } from \"react\";\n\nexport function MetaMaskColorIcon({ style }: { style?: CSSProperties }) {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n style={style}\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <g clipPath=\"url(#clip0_2567_1088)\">\n <path\n d=\"M19.8188 19.418L15.9421 18.2871L13.0186 19.9994L10.9788 19.9985L8.05356 18.2871L4.17862 19.418L3 15.5193L4.17875 11.1924L3 7.5341L4.17875 3L10.2336 6.54437H13.7639L19.8188 3L20.9976 7.5341L19.8188 11.1924L20.9976 15.5193L19.8188 19.418Z\"\n fill=\"#FF5C16\"\n />\n <path\n d=\"M4.17969 3L10.2347 6.54685L9.99394 8.98101L4.17969 3ZM8.05476 15.5209L10.7189 17.5093L8.05476 18.2869V15.5209ZM10.5059 12.2335L9.99394 8.98275L6.71642 11.1934L6.71464 11.1925V11.1941L6.72479 13.4695L8.05387 12.2336L10.5059 12.2335ZM19.819 3L13.7641 6.54685L14.004 8.98101L19.819 3ZM15.9441 15.5209L13.2798 17.5093L15.9441 18.2869V15.5209ZM17.2833 11.194V11.1924L17.2825 11.1932L14.0049 8.98275L13.4929 12.2335H15.944L17.2739 13.4693L17.2833 11.194Z\"\n fill=\"#FF5C16\"\n />\n <path\n d=\"M8.05369 18.2867L4.17875 19.4177L3 15.5207H8.05369V18.2867ZM10.5049 12.2324L11.245 16.9321L10.2191 14.319L6.72296 13.4691L8.0528 12.2325L10.5049 12.2324ZM15.9438 18.2867L19.8188 19.4177L20.9976 15.5206H15.9438C15.9438 15.5207 15.9438 18.2867 15.9438 18.2867ZM13.4927 12.2324L12.7526 16.9321L13.7783 14.319L17.2748 13.4691L15.944 12.2325L13.4927 12.2324Z\"\n fill=\"#E34807\"\n />\n <path\n d=\"M3 15.5194L4.17875 11.1924H6.71358L6.72283 13.4686L10.2194 14.3185L11.2451 16.9315L10.7178 17.5069L8.05369 15.5185H3V15.5194ZM20.9976 15.5194L19.8188 11.1924H17.2839L17.2746 13.4686L13.7783 14.3185L12.7524 16.9315L13.2796 17.5069L15.9439 15.5185H20.9976V15.5194ZM13.7639 6.54443H10.2336L9.99389 8.97859L11.2453 16.9289H12.7526L14.0047 8.97859L13.7639 6.54443Z\"\n fill=\"#FF8D5D\"\n />\n <path\n d=\"M4.17875 3L3 7.5341L4.17875 11.1924H6.71358L9.99287 8.98114L4.17875 3ZM9.77231 13.1766H8.62399L7.9988 13.7771L10.2202 14.3166L9.77231 13.1757V13.1766ZM19.8188 3L20.9976 7.5341L19.8188 11.1924H17.2839L14.0047 8.98114L19.8188 3ZM14.2269 13.1766H15.3769L16.0021 13.7778L13.7782 14.3184L14.2269 13.1757V13.1766ZM13.0178 18.4484L13.2798 17.5086L12.7524 16.9332H11.244L10.7168 17.5086L10.9787 18.4484\"\n fill=\"#661800\"\n />\n <path\n d=\"M13.0173 18.4482V20.0001H10.9785V18.4482H13.0173Z\"\n fill=\"#C0C4CD\"\n />\n <path\n d=\"M8.05469 18.2854L10.9807 19.9994V18.4475L10.7187 17.5078L8.05469 18.2854ZM15.944 18.2854L13.0179 19.9994V18.4475L13.2799 17.5078L15.944 18.2854Z\"\n fill=\"#E7EBF6\"\n />\n </g>\n <defs>\n <clipPath id=\"clip0_2567_1088\">\n <rect\n width=\"18\"\n height=\"17\"\n fill=\"white\"\n transform=\"translate(3 3)\"\n />\n </clipPath>\n </defs>\n </svg>\n );\n}\n","import type { CSSProperties } from \"react\";\n\nexport function TelegramColorIcon({ style }: { style?: CSSProperties }) {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n style={style}\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21Z\"\n fill=\"url(#paint0_linear_2571_1084)\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M7.07426 11.905C9.69794 10.7619 11.4475 10.0083 12.3229 9.64417C14.8222 8.60458 15.3416 8.424 15.6801 8.41803C15.7546 8.41672 15.921 8.43517 16.0289 8.52267C16.1199 8.59655 16.145 8.69635 16.1569 8.7664C16.1689 8.83645 16.1839 8.99602 16.172 9.1207C16.0366 10.5438 15.4505 13.9973 15.1523 15.5912C15.0262 16.2657 14.7778 16.4918 14.5373 16.514C14.0146 16.562 13.6178 16.1686 13.1115 15.8367C12.3194 15.3175 11.8719 14.9943 11.103 14.4876C10.2145 13.902 10.7905 13.5802 11.2969 13.0542C11.4294 12.9166 13.7322 10.822 13.7768 10.632C13.7824 10.6082 13.7875 10.5196 13.7349 10.4729C13.6823 10.4261 13.6046 10.4421 13.5486 10.4548C13.4691 10.4728 12.2037 11.3092 9.75232 12.964C9.39313 13.2106 9.06779 13.3308 8.7763 13.3245C8.45496 13.3176 7.83681 13.1428 7.37729 12.9934C6.81366 12.8102 6.3657 12.7134 6.40471 12.4022C6.42503 12.2401 6.64821 12.0744 7.07426 11.905Z\"\n fill=\"white\"\n />\n <defs>\n <linearGradient\n id=\"paint0_linear_2571_1084\"\n x1=\"903\"\n y1=\"3\"\n x2=\"903\"\n y2=\"1789.65\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor=\"#2AABEE\" />\n <stop offset=\"1\" stopColor=\"#229ED9\" />\n </linearGradient>\n </defs>\n </svg>\n );\n}\n"],"mappings":"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","names":["PrivateKeySigner","useCallback","useEffect","jsx","jsx","jsxs","jsx","jsxs","useCallback","useEffect"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hfunlabs/hypurr-connect",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
"build": "tsup",
|
|
21
21
|
"dev": "tsup --watch",
|
|
22
22
|
"lint": "eslint .",
|
|
23
|
-
"typecheck": "tsc --noEmit"
|
|
23
|
+
"typecheck": "tsc --noEmit",
|
|
24
|
+
"format": "pnpm prettier --write ."
|
|
24
25
|
},
|
|
25
26
|
"dependencies": {
|
|
26
27
|
"hypurr-grpc": "gitlab:hypurr/hypurr-grpc#dev"
|
|
@@ -33,18 +34,19 @@
|
|
|
33
34
|
"react": ">=18.0.0"
|
|
34
35
|
},
|
|
35
36
|
"devDependencies": {
|
|
36
|
-
"@eslint/js": "^9.
|
|
37
|
+
"@eslint/js": "^9.39.3",
|
|
37
38
|
"@hfunlabs/hyperliquid": "0.30.2-hfunlabs.2",
|
|
38
39
|
"@protobuf-ts/grpcweb-transport": "^2.11.1",
|
|
39
40
|
"@protobuf-ts/runtime-rpc": "^2.11.1",
|
|
40
|
-
"@types/react": "^19.
|
|
41
|
-
"eslint": "^9.
|
|
42
|
-
"eslint-plugin-react-hooks": "^5.
|
|
43
|
-
"framer-motion": "^12.
|
|
44
|
-
"globals": "^15.
|
|
45
|
-
"
|
|
46
|
-
"
|
|
41
|
+
"@types/react": "^19.2.14",
|
|
42
|
+
"eslint": "^9.39.3",
|
|
43
|
+
"eslint-plugin-react-hooks": "^5.2.0",
|
|
44
|
+
"framer-motion": "^12.34.5",
|
|
45
|
+
"globals": "^15.15.0",
|
|
46
|
+
"prettier": "^3.8.1",
|
|
47
|
+
"react": "^19.2.4",
|
|
48
|
+
"tsup": "^8.5.1",
|
|
47
49
|
"typescript": "~5.9.3",
|
|
48
|
-
"typescript-eslint": "^8.
|
|
50
|
+
"typescript-eslint": "^8.56.1"
|
|
49
51
|
}
|
|
50
52
|
}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
ExchangeClient,
|
|
3
|
+
HttpTransport,
|
|
4
|
+
InfoClient,
|
|
5
|
+
} from "@hfunlabs/hyperliquid";
|
|
2
6
|
import { PrivateKeySigner } from "@hfunlabs/hyperliquid/signing";
|
|
3
7
|
import type { TelegramUserResponse } from "hypurr-grpc/ts/hypurr/telegram/telegram_service";
|
|
4
8
|
import type { TelegramUser as HypurrTelegramUser } from "hypurr-grpc/ts/hypurr/user";
|
package/src/LoginModal.tsx
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
useCallback,
|
|
9
9
|
useEffect,
|
|
10
10
|
useSyncExternalStore,
|
|
11
|
+
type CSSProperties,
|
|
11
12
|
type ReactNode,
|
|
12
13
|
} from "react";
|
|
13
14
|
import { useHypurrConnect } from "./HypurrConnectProvider";
|
|
@@ -22,8 +23,74 @@ export interface LoginModalProps {
|
|
|
22
23
|
|
|
23
24
|
const MOBILE_BREAKPOINT = 640;
|
|
24
25
|
|
|
25
|
-
const
|
|
26
|
-
"flex
|
|
26
|
+
const btnStyle: CSSProperties = {
|
|
27
|
+
display: "flex",
|
|
28
|
+
height: 53,
|
|
29
|
+
width: "100%",
|
|
30
|
+
alignItems: "center",
|
|
31
|
+
gap: 12,
|
|
32
|
+
overflow: "hidden",
|
|
33
|
+
borderRadius: 6,
|
|
34
|
+
background: "rgba(255,255,255,0.05)",
|
|
35
|
+
padding: "0 24px",
|
|
36
|
+
fontSize: 14,
|
|
37
|
+
fontWeight: 600,
|
|
38
|
+
letterSpacing: "-0.01em",
|
|
39
|
+
color: "#fff",
|
|
40
|
+
cursor: "pointer",
|
|
41
|
+
border: "none",
|
|
42
|
+
transition: "background 150ms",
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const btnHoverBg = { background: "rgba(255,255,255,0.1)" };
|
|
46
|
+
|
|
47
|
+
const backdropStyle: CSSProperties = {
|
|
48
|
+
position: "fixed",
|
|
49
|
+
inset: 0,
|
|
50
|
+
zIndex: 100,
|
|
51
|
+
background: "rgba(0,0,0,0.6)",
|
|
52
|
+
backdropFilter: "blur(2px)",
|
|
53
|
+
WebkitBackdropFilter: "blur(2px)",
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const modalWrapperStyle: CSSProperties = {
|
|
57
|
+
position: "fixed",
|
|
58
|
+
inset: 0,
|
|
59
|
+
zIndex: 101,
|
|
60
|
+
display: "flex",
|
|
61
|
+
alignItems: "center",
|
|
62
|
+
justifyContent: "center",
|
|
63
|
+
padding: 16,
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const modalBoxStyle: CSSProperties = {
|
|
67
|
+
display: "flex",
|
|
68
|
+
width: 400,
|
|
69
|
+
flexDirection: "column",
|
|
70
|
+
alignItems: "center",
|
|
71
|
+
gap: 16,
|
|
72
|
+
overflow: "hidden",
|
|
73
|
+
borderRadius: 12,
|
|
74
|
+
border: "1px solid rgba(255,255,255,0.1)",
|
|
75
|
+
background: "#282828",
|
|
76
|
+
padding: 24,
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const headingStyle: CSSProperties = {
|
|
80
|
+
fontSize: 16,
|
|
81
|
+
fontWeight: 700,
|
|
82
|
+
letterSpacing: "-0.025em",
|
|
83
|
+
color: "#fff",
|
|
84
|
+
margin: 0,
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const dividerStyle: CSSProperties = {
|
|
88
|
+
height: 1,
|
|
89
|
+
width: "100%",
|
|
90
|
+
background: "rgba(255,255,255,0.05)",
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const iconSize: CSSProperties = { width: 20, height: 20 };
|
|
27
94
|
|
|
28
95
|
const mobileQuery =
|
|
29
96
|
typeof window !== "undefined"
|
|
@@ -43,6 +110,25 @@ function useIsMobile() {
|
|
|
43
110
|
return useSyncExternalStore(subscribeMobile, getSnapshotMobile, () => false);
|
|
44
111
|
}
|
|
45
112
|
|
|
113
|
+
function HoverButton({
|
|
114
|
+
onClick,
|
|
115
|
+
children,
|
|
116
|
+
}: {
|
|
117
|
+
onClick: () => void;
|
|
118
|
+
children: ReactNode;
|
|
119
|
+
}) {
|
|
120
|
+
return (
|
|
121
|
+
<motion.button
|
|
122
|
+
type="button"
|
|
123
|
+
onClick={onClick}
|
|
124
|
+
style={btnStyle}
|
|
125
|
+
whileHover={btnHoverBg}
|
|
126
|
+
>
|
|
127
|
+
{children}
|
|
128
|
+
</motion.button>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
46
132
|
export function LoginModal({ onConnectWallet, walletIcon }: LoginModalProps) {
|
|
47
133
|
const { loginTelegram, loginModalOpen, closeLoginModal, botId } =
|
|
48
134
|
useHypurrConnect();
|
|
@@ -99,26 +185,33 @@ export function LoginModal({ onConnectWallet, walletIcon }: LoginModalProps) {
|
|
|
99
185
|
|
|
100
186
|
const modalContent = (
|
|
101
187
|
<>
|
|
102
|
-
<div
|
|
103
|
-
|
|
104
|
-
|
|
188
|
+
<div
|
|
189
|
+
style={{
|
|
190
|
+
display: "flex",
|
|
191
|
+
width: "100%",
|
|
192
|
+
flexDirection: "column",
|
|
193
|
+
alignItems: "center",
|
|
194
|
+
gap: 8,
|
|
195
|
+
overflow: "hidden",
|
|
196
|
+
}}
|
|
197
|
+
>
|
|
198
|
+
<HoverButton onClick={openTelegramOAuth}>
|
|
199
|
+
<TelegramColorIcon style={iconSize} />
|
|
105
200
|
Telegram
|
|
106
|
-
</
|
|
201
|
+
</HoverButton>
|
|
107
202
|
</div>
|
|
108
203
|
|
|
109
|
-
<div
|
|
204
|
+
<div style={dividerStyle} />
|
|
110
205
|
|
|
111
|
-
<
|
|
112
|
-
type="button"
|
|
206
|
+
<HoverButton
|
|
113
207
|
onClick={() => {
|
|
114
208
|
closeLoginModal();
|
|
115
209
|
onConnectWallet();
|
|
116
210
|
}}
|
|
117
|
-
className={btnClass}
|
|
118
211
|
>
|
|
119
|
-
{walletIcon ?? <MetaMaskColorIcon
|
|
212
|
+
{walletIcon ?? <MetaMaskColorIcon style={iconSize} />}
|
|
120
213
|
Wallet
|
|
121
|
-
</
|
|
214
|
+
</HoverButton>
|
|
122
215
|
</>
|
|
123
216
|
);
|
|
124
217
|
|
|
@@ -133,7 +226,7 @@ export function LoginModal({ onConnectWallet, walletIcon }: LoginModalProps) {
|
|
|
133
226
|
<>
|
|
134
227
|
<motion.div
|
|
135
228
|
key="backdrop"
|
|
136
|
-
|
|
229
|
+
style={backdropStyle}
|
|
137
230
|
initial={{ opacity: 0 }}
|
|
138
231
|
animate={{ opacity: 1 }}
|
|
139
232
|
exit={{ opacity: 0 }}
|
|
@@ -142,7 +235,7 @@ export function LoginModal({ onConnectWallet, walletIcon }: LoginModalProps) {
|
|
|
142
235
|
/>
|
|
143
236
|
<motion.div
|
|
144
237
|
key="modal-wrapper"
|
|
145
|
-
|
|
238
|
+
style={modalWrapperStyle}
|
|
146
239
|
initial={{ opacity: 0 }}
|
|
147
240
|
animate={{ opacity: 1 }}
|
|
148
241
|
exit={{ opacity: 0 }}
|
|
@@ -150,16 +243,14 @@ export function LoginModal({ onConnectWallet, walletIcon }: LoginModalProps) {
|
|
|
150
243
|
onClick={closeLoginModal}
|
|
151
244
|
>
|
|
152
245
|
<motion.div
|
|
153
|
-
|
|
246
|
+
style={modalBoxStyle}
|
|
154
247
|
initial={{ opacity: 0, scale: 0.95, y: 10 }}
|
|
155
248
|
animate={{ opacity: 1, scale: 1, y: 0 }}
|
|
156
249
|
exit={{ opacity: 0, scale: 0.95, y: 10 }}
|
|
157
250
|
transition={{ duration: 0.2, ease: "easeOut" }}
|
|
158
251
|
onClick={(e) => e.stopPropagation()}
|
|
159
252
|
>
|
|
160
|
-
<p
|
|
161
|
-
Connect
|
|
162
|
-
</p>
|
|
253
|
+
<p style={headingStyle}>Connect</p>
|
|
163
254
|
{modalContent}
|
|
164
255
|
</motion.div>
|
|
165
256
|
</motion.div>
|
|
@@ -169,6 +260,51 @@ export function LoginModal({ onConnectWallet, walletIcon }: LoginModalProps) {
|
|
|
169
260
|
);
|
|
170
261
|
}
|
|
171
262
|
|
|
263
|
+
const drawerSheetStyle: CSSProperties = {
|
|
264
|
+
position: "fixed",
|
|
265
|
+
left: 0,
|
|
266
|
+
right: 0,
|
|
267
|
+
bottom: 0,
|
|
268
|
+
zIndex: 101,
|
|
269
|
+
display: "flex",
|
|
270
|
+
flexDirection: "column",
|
|
271
|
+
alignItems: "center",
|
|
272
|
+
gap: 16,
|
|
273
|
+
borderTopLeftRadius: 12,
|
|
274
|
+
borderTopRightRadius: 12,
|
|
275
|
+
borderLeft: "1px solid rgba(255,255,255,0.1)",
|
|
276
|
+
borderRight: "1px solid rgba(255,255,255,0.1)",
|
|
277
|
+
borderTop: "1px solid rgba(255,255,255,0.1)",
|
|
278
|
+
background: "#282828",
|
|
279
|
+
padding: "12px 24px max(24px, env(safe-area-inset-bottom))",
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
const drawerBgStyle: CSSProperties = {
|
|
283
|
+
position: "absolute",
|
|
284
|
+
left: 0,
|
|
285
|
+
right: 0,
|
|
286
|
+
top: 0,
|
|
287
|
+
bottom: "-100vh",
|
|
288
|
+
zIndex: -1,
|
|
289
|
+
background: "#282828",
|
|
290
|
+
borderTopLeftRadius: 12,
|
|
291
|
+
borderTopRightRadius: 12,
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
const grabHandleAreaStyle: CSSProperties = {
|
|
295
|
+
width: "100%",
|
|
296
|
+
cursor: "grab",
|
|
297
|
+
paddingBottom: 4,
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
const grabHandleStyle: CSSProperties = {
|
|
301
|
+
margin: "0 auto",
|
|
302
|
+
height: 4,
|
|
303
|
+
width: 100,
|
|
304
|
+
borderRadius: 9999,
|
|
305
|
+
background: "rgba(255,255,255,0.05)",
|
|
306
|
+
};
|
|
307
|
+
|
|
172
308
|
function MobileDrawer({
|
|
173
309
|
children,
|
|
174
310
|
onClose,
|
|
@@ -193,7 +329,7 @@ function MobileDrawer({
|
|
|
193
329
|
<>
|
|
194
330
|
<motion.div
|
|
195
331
|
key="drawer-backdrop"
|
|
196
|
-
|
|
332
|
+
style={backdropStyle}
|
|
197
333
|
initial={{ opacity: 0 }}
|
|
198
334
|
animate={{ opacity: 1 }}
|
|
199
335
|
exit={{ opacity: 0 }}
|
|
@@ -203,7 +339,7 @@ function MobileDrawer({
|
|
|
203
339
|
|
|
204
340
|
<motion.div
|
|
205
341
|
key="drawer-sheet"
|
|
206
|
-
|
|
342
|
+
style={drawerSheetStyle}
|
|
207
343
|
initial={{ y: "100%" }}
|
|
208
344
|
animate={{ y: 0 }}
|
|
209
345
|
exit={{ y: "100%" }}
|
|
@@ -213,15 +349,13 @@ function MobileDrawer({
|
|
|
213
349
|
dragElastic={{ top: 0, bottom: 0.4 }}
|
|
214
350
|
onDragEnd={handleDragEnd}
|
|
215
351
|
>
|
|
216
|
-
<div
|
|
352
|
+
<div style={drawerBgStyle} />
|
|
217
353
|
|
|
218
|
-
<div
|
|
219
|
-
<div
|
|
354
|
+
<div style={grabHandleAreaStyle}>
|
|
355
|
+
<div style={grabHandleStyle} />
|
|
220
356
|
</div>
|
|
221
357
|
|
|
222
|
-
<p
|
|
223
|
-
Connect
|
|
224
|
-
</p>
|
|
358
|
+
<p style={headingStyle}>Connect</p>
|
|
225
359
|
|
|
226
360
|
{children}
|
|
227
361
|
</motion.div>
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
import type { CSSProperties } from "react";
|
|
2
|
+
|
|
3
|
+
export function MetaMaskColorIcon({ style }: { style?: CSSProperties }) {
|
|
2
4
|
return (
|
|
3
5
|
<svg
|
|
4
6
|
width="24"
|
|
5
7
|
height="24"
|
|
6
8
|
viewBox="0 0 24 24"
|
|
7
|
-
|
|
9
|
+
style={style}
|
|
8
10
|
fill="none"
|
|
9
11
|
xmlns="http://www.w3.org/2000/svg"
|
|
10
12
|
>
|
|
11
|
-
<g
|
|
13
|
+
<g clipPath="url(#clip0_2567_1088)">
|
|
12
14
|
<path
|
|
13
15
|
d="M19.8188 19.418L15.9421 18.2871L13.0186 19.9994L10.9788 19.9985L8.05356 18.2871L4.17862 19.418L3 15.5193L4.17875 11.1924L3 7.5341L4.17875 3L10.2336 6.54437H13.7639L19.8188 3L20.9976 7.5341L19.8188 11.1924L20.9976 15.5193L19.8188 19.418Z"
|
|
14
16
|
fill="#FF5C16"
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
import type { CSSProperties } from "react";
|
|
2
|
+
|
|
3
|
+
export function TelegramColorIcon({ style }: { style?: CSSProperties }) {
|
|
2
4
|
return (
|
|
3
5
|
<svg
|
|
4
6
|
width="24"
|
|
5
7
|
height="24"
|
|
6
8
|
viewBox="0 0 24 24"
|
|
7
|
-
|
|
9
|
+
style={style}
|
|
8
10
|
fill="none"
|
|
9
11
|
xmlns="http://www.w3.org/2000/svg"
|
|
10
12
|
>
|
|
@@ -13,8 +15,8 @@ export function TelegramColorIcon({ className }: { className?: string }) {
|
|
|
13
15
|
fill="url(#paint0_linear_2571_1084)"
|
|
14
16
|
/>
|
|
15
17
|
<path
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
fillRule="evenodd"
|
|
19
|
+
clipRule="evenodd"
|
|
18
20
|
d="M7.07426 11.905C9.69794 10.7619 11.4475 10.0083 12.3229 9.64417C14.8222 8.60458 15.3416 8.424 15.6801 8.41803C15.7546 8.41672 15.921 8.43517 16.0289 8.52267C16.1199 8.59655 16.145 8.69635 16.1569 8.7664C16.1689 8.83645 16.1839 8.99602 16.172 9.1207C16.0366 10.5438 15.4505 13.9973 15.1523 15.5912C15.0262 16.2657 14.7778 16.4918 14.5373 16.514C14.0146 16.562 13.6178 16.1686 13.1115 15.8367C12.3194 15.3175 11.8719 14.9943 11.103 14.4876C10.2145 13.902 10.7905 13.5802 11.2969 13.0542C11.4294 12.9166 13.7322 10.822 13.7768 10.632C13.7824 10.6082 13.7875 10.5196 13.7349 10.4729C13.6823 10.4261 13.6046 10.4421 13.5486 10.4548C13.4691 10.4728 12.2037 11.3092 9.75232 12.964C9.39313 13.2106 9.06779 13.3308 8.7763 13.3245C8.45496 13.3176 7.83681 13.1428 7.37729 12.9934C6.81366 12.8102 6.3657 12.7134 6.40471 12.4022C6.42503 12.2401 6.64821 12.0744 7.07426 11.905Z"
|
|
19
21
|
fill="white"
|
|
20
22
|
/>
|
|
@@ -27,8 +29,8 @@ export function TelegramColorIcon({ className }: { className?: string }) {
|
|
|
27
29
|
y2="1789.65"
|
|
28
30
|
gradientUnits="userSpaceOnUse"
|
|
29
31
|
>
|
|
30
|
-
<stop
|
|
31
|
-
<stop offset="1"
|
|
32
|
+
<stop stopColor="#2AABEE" />
|
|
33
|
+
<stop offset="1" stopColor="#229ED9" />
|
|
32
34
|
</linearGradient>
|
|
33
35
|
</defs>
|
|
34
36
|
</svg>
|