@forge-connect/react 1.0.10 → 1.0.12
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.cjs +275 -182
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +300 -207
- package/dist/index.js.map +1 -1
- package/dist/styles.css +45 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -16,8 +16,16 @@ var ForgeConnectApiError = class extends Error {
|
|
|
16
16
|
this.code = code;
|
|
17
17
|
}
|
|
18
18
|
};
|
|
19
|
+
var clientCache = /* @__PURE__ */ new Map();
|
|
19
20
|
function createApiClient(apiUrl) {
|
|
20
21
|
const base = apiUrl.replace(/\/+$/, "");
|
|
22
|
+
const cached = clientCache.get(base);
|
|
23
|
+
if (cached) return cached;
|
|
24
|
+
const client = buildApiClient(base);
|
|
25
|
+
clientCache.set(base, client);
|
|
26
|
+
return client;
|
|
27
|
+
}
|
|
28
|
+
function buildApiClient(base) {
|
|
21
29
|
const inflightRequests = /* @__PURE__ */ new Map();
|
|
22
30
|
let inflightRefresh = null;
|
|
23
31
|
async function request(path, options = {}) {
|
|
@@ -486,7 +494,7 @@ function ModalOverlay({ isOpen, onClose, children }) {
|
|
|
486
494
|
import { useState } from "react";
|
|
487
495
|
|
|
488
496
|
// src/resolve-config.ts
|
|
489
|
-
var OAUTH_PROVIDERS = /* @__PURE__ */ new Set(["google", "discord", "twitter", "apple", "telegram"]);
|
|
497
|
+
var OAUTH_PROVIDERS = /* @__PURE__ */ new Set(["google", "discord", "twitter", "apple", "telegram", "matrica"]);
|
|
490
498
|
function isOAuthMethod(method) {
|
|
491
499
|
return OAUTH_PROVIDERS.has(method);
|
|
492
500
|
}
|
|
@@ -826,8 +834,105 @@ function EmailOtpForm() {
|
|
|
826
834
|
}
|
|
827
835
|
|
|
828
836
|
// src/components/tabs/wallet-connect.tsx
|
|
829
|
-
import { useState as useState3, useMemo, useRef as
|
|
830
|
-
|
|
837
|
+
import { useState as useState3, useMemo, useRef as useRef4, useCallback } from "react";
|
|
838
|
+
|
|
839
|
+
// src/components/svg-icon.tsx
|
|
840
|
+
import { useRef as useRef3, useEffect as useEffect2 } from "react";
|
|
841
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
842
|
+
function SvgIcon({ svg, className }) {
|
|
843
|
+
const ref = useRef3(null);
|
|
844
|
+
useEffect2(() => {
|
|
845
|
+
if (!ref.current || !svg) return;
|
|
846
|
+
try {
|
|
847
|
+
const doc = new DOMParser().parseFromString(svg, "text/html");
|
|
848
|
+
const svgEl = doc.body.querySelector("svg");
|
|
849
|
+
if (!svgEl) {
|
|
850
|
+
ref.current.textContent = "";
|
|
851
|
+
return;
|
|
852
|
+
}
|
|
853
|
+
const dangerous = svgEl.querySelectorAll("script,iframe,object,embed,foreignObject");
|
|
854
|
+
dangerous.forEach((el) => el.remove());
|
|
855
|
+
const all = svgEl.querySelectorAll("*");
|
|
856
|
+
all.forEach((el) => {
|
|
857
|
+
for (const attr of Array.from(el.attributes)) {
|
|
858
|
+
if (attr.name.startsWith("on")) {
|
|
859
|
+
el.removeAttribute(attr.name);
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
});
|
|
863
|
+
ref.current.textContent = "";
|
|
864
|
+
ref.current.appendChild(svgEl);
|
|
865
|
+
} catch {
|
|
866
|
+
ref.current.textContent = "";
|
|
867
|
+
}
|
|
868
|
+
}, [svg]);
|
|
869
|
+
return /* @__PURE__ */ jsx4("span", { ref, className });
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
// src/components/tabs/oauth-buttons.tsx
|
|
873
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
874
|
+
var PROVIDER_INFO = {
|
|
875
|
+
google: {
|
|
876
|
+
label: "Google",
|
|
877
|
+
icon: '<svg viewBox="0 0 24 24" width="20" height="20"><path d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92a5.06 5.06 0 0 1-2.2 3.32v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.1z" fill="#4285F4"/><path d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z" fill="#34A853"/><path d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z" fill="#FBBC05"/><path d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z" fill="#EA4335"/></svg>'
|
|
878
|
+
},
|
|
879
|
+
discord: {
|
|
880
|
+
label: "Discord",
|
|
881
|
+
icon: '<svg viewBox="0 0 24 24" width="20" height="20"><path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128c.126-.094.252-.192.372-.292a.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03z" fill="#5865F2"/></svg>'
|
|
882
|
+
},
|
|
883
|
+
twitter: {
|
|
884
|
+
label: "Twitter",
|
|
885
|
+
icon: '<svg viewBox="0 0 24 24" width="20" height="20"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" fill="currentColor"/></svg>'
|
|
886
|
+
},
|
|
887
|
+
apple: {
|
|
888
|
+
label: "Apple",
|
|
889
|
+
icon: '<svg viewBox="0 0 24 24" width="20" height="20"><path d="M17.05 20.28c-.98.95-2.05.88-3.08.4-1.09-.5-2.08-.52-3.23 0-1.44.64-2.2.45-3.06-.4C3.79 16.17 4.36 9.02 8.8 8.78c1.27.06 2.15.72 2.91.76.93-.19 1.82-.88 2.83-.8 1.21.1 2.12.58 2.72 1.49-2.46 1.48-1.88 4.73.52 5.64-.42 1.13-.98 2.24-1.73 3.41zM12.03 8.7c-.12-2.35 1.82-4.38 4.04-4.54.29 2.56-2.34 4.68-4.04 4.54z" fill="currentColor"/></svg>'
|
|
890
|
+
},
|
|
891
|
+
telegram: {
|
|
892
|
+
label: "Telegram",
|
|
893
|
+
icon: '<svg viewBox="0 0 24 24" width="20" height="20"><path d="M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.479.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z" fill="#2AABEE"/></svg>'
|
|
894
|
+
},
|
|
895
|
+
matrica: {
|
|
896
|
+
label: "Matrica",
|
|
897
|
+
icon: '<svg viewBox="2 1 26 26" width="20" height="20" xmlns="http://www.w3.org/2000/svg"><rect x="11.457" y="10.6387" width="7.00961" height="7.00962" fill="#4A99BF"/><path d="M12.6266 1.87695V5.08969H5.90903V23.1979H12.6266V26.4106H2.69629V1.87695H12.6266Z" fill="#4A99BF"/><path d="M17.2997 26.4106H27.2299V1.87695H17.2997V5.08969H24.0172V23.1979H17.2997V26.4106Z" fill="#4A99BF"/></svg>'
|
|
898
|
+
}
|
|
899
|
+
};
|
|
900
|
+
function OAuthButton({ provider }) {
|
|
901
|
+
const { loginWithOAuth } = useForgeConnect();
|
|
902
|
+
const info = PROVIDER_INFO[provider];
|
|
903
|
+
return /* @__PURE__ */ jsxs4(
|
|
904
|
+
"button",
|
|
905
|
+
{
|
|
906
|
+
type: "button",
|
|
907
|
+
className: "fc-btn fc-btn-oauth",
|
|
908
|
+
onClick: () => loginWithOAuth(provider),
|
|
909
|
+
children: [
|
|
910
|
+
/* @__PURE__ */ jsx5(SvgIcon, { svg: info.icon, className: "fc-oauth-icon" }),
|
|
911
|
+
/* @__PURE__ */ jsx5("span", { className: "fc-btn-name", children: info.label })
|
|
912
|
+
]
|
|
913
|
+
}
|
|
914
|
+
);
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
// src/components/tabs/wallet-connect.tsx
|
|
918
|
+
import { Fragment, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
919
|
+
function MatricaWalletEntry() {
|
|
920
|
+
const { loginWithOAuth } = useForgeConnect();
|
|
921
|
+
const info = PROVIDER_INFO.matrica;
|
|
922
|
+
return /* @__PURE__ */ jsxs5(
|
|
923
|
+
"button",
|
|
924
|
+
{
|
|
925
|
+
type: "button",
|
|
926
|
+
className: "fc-btn fc-btn-wallet",
|
|
927
|
+
onClick: () => loginWithOAuth("matrica"),
|
|
928
|
+
children: [
|
|
929
|
+
/* @__PURE__ */ jsx6(SvgIcon, { svg: info.icon, className: "fc-oauth-icon" }),
|
|
930
|
+
/* @__PURE__ */ jsx6("span", { className: "fc-wallet-name", children: info.label }),
|
|
931
|
+
/* @__PURE__ */ jsx6("span", { className: "fc-badge-preferred", children: "Brings wallets" })
|
|
932
|
+
]
|
|
933
|
+
}
|
|
934
|
+
);
|
|
935
|
+
}
|
|
831
936
|
var MOBILE_WALLETS = [
|
|
832
937
|
{
|
|
833
938
|
name: "Phantom",
|
|
@@ -854,22 +959,22 @@ function WalletConnectForm() {
|
|
|
854
959
|
const methods = resolveLoginMethods(config);
|
|
855
960
|
const showBack = methods.length > 1;
|
|
856
961
|
if (!walletAdapter && isMobile()) {
|
|
857
|
-
return /* @__PURE__ */
|
|
962
|
+
return /* @__PURE__ */ jsx6(MobileWalletFlow, {});
|
|
858
963
|
}
|
|
859
964
|
if (walletAdapter) {
|
|
860
|
-
return /* @__PURE__ */
|
|
965
|
+
return /* @__PURE__ */ jsx6(WalletAdapterFlow, {});
|
|
861
966
|
}
|
|
862
|
-
return /* @__PURE__ */
|
|
863
|
-
/* @__PURE__ */
|
|
864
|
-
/* @__PURE__ */
|
|
967
|
+
return /* @__PURE__ */ jsxs5("div", { className: "fc-tab", children: [
|
|
968
|
+
/* @__PURE__ */ jsx6("h3", { className: "fc-tab-title", children: "Connect wallet" }),
|
|
969
|
+
/* @__PURE__ */ jsxs5("p", { className: "fc-text", children: [
|
|
865
970
|
"No wallet adapter detected. Pass ",
|
|
866
|
-
/* @__PURE__ */
|
|
971
|
+
/* @__PURE__ */ jsx6("code", { children: "walletAdapter" }),
|
|
867
972
|
" to",
|
|
868
973
|
" ",
|
|
869
|
-
/* @__PURE__ */
|
|
974
|
+
/* @__PURE__ */ jsx6("code", { children: "<ForgeConnectProvider>" }),
|
|
870
975
|
" to enable wallet login."
|
|
871
976
|
] }),
|
|
872
|
-
showBack && /* @__PURE__ */
|
|
977
|
+
showBack && /* @__PURE__ */ jsx6("p", { className: "fc-switch", children: /* @__PURE__ */ jsx6("button", { type: "button", className: "fc-link", onClick: () => setModalStep("method-select"), children: "Back" }) })
|
|
873
978
|
] });
|
|
874
979
|
}
|
|
875
980
|
function MobileWalletFlow() {
|
|
@@ -893,23 +998,27 @@ function MobileWalletFlow() {
|
|
|
893
998
|
const pageUrl = window.location.href;
|
|
894
999
|
window.location.href = mw.buildUrl(pageUrl);
|
|
895
1000
|
};
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
{
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
1001
|
+
const showMatrica = methods.includes("matrica");
|
|
1002
|
+
return /* @__PURE__ */ jsxs5("div", { className: "fc-tab", children: [
|
|
1003
|
+
/* @__PURE__ */ jsxs5("div", { className: "fc-wallet-list", children: [
|
|
1004
|
+
showMatrica && /* @__PURE__ */ jsx6(MatricaWalletEntry, {}),
|
|
1005
|
+
walletsToShow.map((mw) => /* @__PURE__ */ jsxs5(
|
|
1006
|
+
"button",
|
|
1007
|
+
{
|
|
1008
|
+
type: "button",
|
|
1009
|
+
className: "fc-btn fc-btn-wallet",
|
|
1010
|
+
onClick: () => handleOpen(mw),
|
|
1011
|
+
children: [
|
|
1012
|
+
/* @__PURE__ */ jsx6("span", { style: { position: "relative", display: "inline-flex" }, children: /* @__PURE__ */ jsx6("img", { src: mw.icon, alt: "", className: "fc-wallet-icon" }) }),
|
|
1013
|
+
/* @__PURE__ */ jsx6("span", { className: "fc-wallet-name", children: mw.name }),
|
|
1014
|
+
/* @__PURE__ */ jsx6("span", { className: "fc-badge-preferred", children: "Open app" })
|
|
1015
|
+
]
|
|
1016
|
+
},
|
|
1017
|
+
mw.name
|
|
1018
|
+
))
|
|
1019
|
+
] }),
|
|
1020
|
+
/* @__PURE__ */ jsx6("p", { className: "fc-text", style: { textAlign: "center", fontSize: 12, opacity: 0.6 }, children: "You'll be redirected to the wallet app to sign in." }),
|
|
1021
|
+
showBack && /* @__PURE__ */ jsx6("p", { className: "fc-switch", children: /* @__PURE__ */ jsx6("button", { type: "button", className: "fc-link", onClick: () => setModalStep("method-select"), children: "Back" }) })
|
|
913
1022
|
] });
|
|
914
1023
|
}
|
|
915
1024
|
function WalletAdapterFlow() {
|
|
@@ -923,7 +1032,7 @@ function WalletAdapterFlow() {
|
|
|
923
1032
|
const [showOther, setShowOther] = useState3(false);
|
|
924
1033
|
const [coldWallet, setColdWallet] = useState3(false);
|
|
925
1034
|
const mobile = useMemo(() => isMobile(), []);
|
|
926
|
-
const coldWalletRef =
|
|
1035
|
+
const coldWalletRef = useRef4(coldWallet);
|
|
927
1036
|
coldWalletRef.current = coldWallet;
|
|
928
1037
|
const buildSignTxFnForAdapter = useCallback((adapter) => {
|
|
929
1038
|
if (!adapter.signTransaction) return void 0;
|
|
@@ -995,13 +1104,13 @@ function WalletAdapterFlow() {
|
|
|
995
1104
|
const adapterNames = new Set(wallet.wallets.map((w) => w.adapter.name));
|
|
996
1105
|
return MOBILE_WALLETS.filter((mw) => !adapterNames.has(mw.name));
|
|
997
1106
|
}, [mobile, wallet.wallets]);
|
|
998
|
-
return /* @__PURE__ */
|
|
999
|
-
loading ? /* @__PURE__ */
|
|
1000
|
-
/* @__PURE__ */
|
|
1001
|
-
/* @__PURE__ */
|
|
1002
|
-
error && /* @__PURE__ */
|
|
1003
|
-
/* @__PURE__ */
|
|
1004
|
-
/* @__PURE__ */
|
|
1107
|
+
return /* @__PURE__ */ jsxs5("div", { className: "fc-tab", children: [
|
|
1108
|
+
loading ? /* @__PURE__ */ jsxs5("div", { style: { textAlign: "center", padding: "24px 0" }, children: [
|
|
1109
|
+
/* @__PURE__ */ jsx6("p", { className: "fc-tab-title", children: "Connecting..." }),
|
|
1110
|
+
/* @__PURE__ */ jsx6("p", { className: "fc-text", children: coldWallet ? "Confirm the transaction on your device" : "Approve the connection, then sign the verification request in your wallet" }),
|
|
1111
|
+
error && /* @__PURE__ */ jsxs5(Fragment, { children: [
|
|
1112
|
+
/* @__PURE__ */ jsx6("p", { className: "fc-error", children: error }),
|
|
1113
|
+
/* @__PURE__ */ jsx6(
|
|
1005
1114
|
"button",
|
|
1006
1115
|
{
|
|
1007
1116
|
type: "button",
|
|
@@ -1015,78 +1124,79 @@ function WalletAdapterFlow() {
|
|
|
1015
1124
|
}
|
|
1016
1125
|
)
|
|
1017
1126
|
] })
|
|
1018
|
-
] }) : /* @__PURE__ */
|
|
1019
|
-
/* @__PURE__ */
|
|
1127
|
+
] }) : /* @__PURE__ */ jsxs5(Fragment, { children: [
|
|
1128
|
+
/* @__PURE__ */ jsxs5("div", { className: "fc-wallet-list", children: [
|
|
1129
|
+
methods.includes("matrica") && /* @__PURE__ */ jsx6(MatricaWalletEntry, {}),
|
|
1020
1130
|
preferredWallets.map((w) => {
|
|
1021
1131
|
const installed = w.readyState === "Installed";
|
|
1022
1132
|
const isConnected = w.adapter.name === connectedWalletName;
|
|
1023
|
-
return /* @__PURE__ */
|
|
1133
|
+
return /* @__PURE__ */ jsxs5(
|
|
1024
1134
|
"button",
|
|
1025
1135
|
{
|
|
1026
1136
|
type: "button",
|
|
1027
1137
|
className: "fc-btn fc-btn-wallet",
|
|
1028
1138
|
onClick: () => handleConnect(w),
|
|
1029
1139
|
children: [
|
|
1030
|
-
/* @__PURE__ */
|
|
1031
|
-
/* @__PURE__ */
|
|
1032
|
-
isConnected ? /* @__PURE__ */
|
|
1033
|
-
!installed && mobile && MOBILE_WALLETS.some((mw) => mw.name === w.adapter.name) ? /* @__PURE__ */
|
|
1140
|
+
/* @__PURE__ */ jsx6("span", { className: installed ? "fc-installed-dot" : "", style: { position: "relative", display: "inline-flex" }, children: /* @__PURE__ */ jsx6("img", { src: w.adapter.icon, alt: "", className: "fc-wallet-icon" }) }),
|
|
1141
|
+
/* @__PURE__ */ jsx6("span", { className: "fc-wallet-name", children: w.adapter.name }),
|
|
1142
|
+
isConnected ? /* @__PURE__ */ jsx6("span", { className: "fc-badge-preferred", children: "Last used" }) : /* @__PURE__ */ jsx6("span", { className: "fc-badge-preferred", children: "Preferred" }),
|
|
1143
|
+
!installed && mobile && MOBILE_WALLETS.some((mw) => mw.name === w.adapter.name) ? /* @__PURE__ */ jsx6("span", { className: "fc-badge-install", children: "Open app" }) : !installed && /* @__PURE__ */ jsx6("span", { className: "fc-badge-install", children: "Install" })
|
|
1034
1144
|
]
|
|
1035
1145
|
},
|
|
1036
1146
|
w.adapter.name
|
|
1037
1147
|
);
|
|
1038
1148
|
}),
|
|
1039
|
-
mobileExtraWallets.map((mw) => /* @__PURE__ */
|
|
1149
|
+
mobileExtraWallets.map((mw) => /* @__PURE__ */ jsxs5(
|
|
1040
1150
|
"button",
|
|
1041
1151
|
{
|
|
1042
1152
|
type: "button",
|
|
1043
1153
|
className: "fc-btn fc-btn-wallet",
|
|
1044
1154
|
onClick: () => handleMobileOpen(mw),
|
|
1045
1155
|
children: [
|
|
1046
|
-
/* @__PURE__ */
|
|
1047
|
-
/* @__PURE__ */
|
|
1048
|
-
/* @__PURE__ */
|
|
1156
|
+
/* @__PURE__ */ jsx6("span", { style: { position: "relative", display: "inline-flex" }, children: /* @__PURE__ */ jsx6("img", { src: mw.icon, alt: "", className: "fc-wallet-icon" }) }),
|
|
1157
|
+
/* @__PURE__ */ jsx6("span", { className: "fc-wallet-name", children: mw.name }),
|
|
1158
|
+
/* @__PURE__ */ jsx6("span", { className: "fc-badge-install", children: "Open app" })
|
|
1049
1159
|
]
|
|
1050
1160
|
},
|
|
1051
1161
|
mw.name
|
|
1052
1162
|
)),
|
|
1053
|
-
otherWallets.length > 0 && !showOther && /* @__PURE__ */
|
|
1163
|
+
otherWallets.length > 0 && !showOther && /* @__PURE__ */ jsxs5(
|
|
1054
1164
|
"button",
|
|
1055
1165
|
{
|
|
1056
1166
|
type: "button",
|
|
1057
1167
|
className: "fc-btn fc-btn-wallet",
|
|
1058
1168
|
onClick: () => setShowOther(true),
|
|
1059
1169
|
children: [
|
|
1060
|
-
/* @__PURE__ */
|
|
1061
|
-
/* @__PURE__ */
|
|
1062
|
-
/* @__PURE__ */
|
|
1063
|
-
/* @__PURE__ */
|
|
1170
|
+
/* @__PURE__ */ jsx6("span", { className: "fc-other-wallets-icon", children: /* @__PURE__ */ jsxs5("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", children: [
|
|
1171
|
+
/* @__PURE__ */ jsx6("rect", { x: "2", y: "3", width: "16", height: "14", rx: "2", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
1172
|
+
/* @__PURE__ */ jsx6("path", { d: "M2 7h16", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
1173
|
+
/* @__PURE__ */ jsx6("rect", { x: "11", y: "10", width: "7", height: "4", rx: "1", stroke: "currentColor", strokeWidth: "1.5" })
|
|
1064
1174
|
] }) }),
|
|
1065
|
-
/* @__PURE__ */
|
|
1175
|
+
/* @__PURE__ */ jsx6("span", { className: "fc-wallet-name", children: "Other wallets" })
|
|
1066
1176
|
]
|
|
1067
1177
|
}
|
|
1068
1178
|
),
|
|
1069
1179
|
showOther && otherWallets.map((w) => {
|
|
1070
1180
|
const isConnected = w.adapter.name === connectedWalletName;
|
|
1071
|
-
return /* @__PURE__ */
|
|
1181
|
+
return /* @__PURE__ */ jsxs5(
|
|
1072
1182
|
"button",
|
|
1073
1183
|
{
|
|
1074
1184
|
type: "button",
|
|
1075
1185
|
className: "fc-btn fc-btn-wallet",
|
|
1076
1186
|
onClick: () => handleConnect(w),
|
|
1077
1187
|
children: [
|
|
1078
|
-
/* @__PURE__ */
|
|
1079
|
-
/* @__PURE__ */
|
|
1080
|
-
isConnected && /* @__PURE__ */
|
|
1188
|
+
/* @__PURE__ */ jsx6("span", { className: "fc-installed-dot", style: { position: "relative", display: "inline-flex" }, children: /* @__PURE__ */ jsx6("img", { src: w.adapter.icon, alt: "", className: "fc-wallet-icon" }) }),
|
|
1189
|
+
/* @__PURE__ */ jsx6("span", { className: "fc-wallet-name", children: w.adapter.name }),
|
|
1190
|
+
isConnected && /* @__PURE__ */ jsx6("span", { className: "fc-badge-preferred", children: "Last used" })
|
|
1081
1191
|
]
|
|
1082
1192
|
},
|
|
1083
1193
|
w.adapter.name
|
|
1084
1194
|
);
|
|
1085
1195
|
})
|
|
1086
1196
|
] }),
|
|
1087
|
-
preferredWallets.length === 0 && otherWallets.length === 0 && mobileExtraWallets.length === 0 && /* @__PURE__ */
|
|
1088
|
-
|
|
1089
|
-
/* @__PURE__ */
|
|
1197
|
+
preferredWallets.length === 0 && otherWallets.length === 0 && mobileExtraWallets.length === 0 && /* @__PURE__ */ jsx6("p", { className: "fc-text", children: "No wallet found. Please install a Solana wallet (like Phantom) to continue." }),
|
|
1198
|
+
/* @__PURE__ */ jsxs5("label", { className: "fc-cold-wallet-toggle", children: [
|
|
1199
|
+
/* @__PURE__ */ jsx6(
|
|
1090
1200
|
"input",
|
|
1091
1201
|
{
|
|
1092
1202
|
type: "checkbox",
|
|
@@ -1094,21 +1204,21 @@ function WalletAdapterFlow() {
|
|
|
1094
1204
|
onChange: (e) => setColdWallet(e.target.checked)
|
|
1095
1205
|
}
|
|
1096
1206
|
),
|
|
1097
|
-
/* @__PURE__ */
|
|
1098
|
-
/* @__PURE__ */
|
|
1099
|
-
/* @__PURE__ */
|
|
1100
|
-
/* @__PURE__ */
|
|
1207
|
+
/* @__PURE__ */ jsx6("span", { className: "fc-toggle-track" }),
|
|
1208
|
+
/* @__PURE__ */ jsxs5("span", { className: "fc-cold-wallet-label", children: [
|
|
1209
|
+
/* @__PURE__ */ jsx6("span", { children: "Hardware wallet" }),
|
|
1210
|
+
/* @__PURE__ */ jsx6("span", { children: "Ledger, Trezor, Keystone..." })
|
|
1101
1211
|
] })
|
|
1102
1212
|
] }),
|
|
1103
|
-
error && /* @__PURE__ */
|
|
1213
|
+
error && /* @__PURE__ */ jsx6("p", { className: "fc-error", children: error })
|
|
1104
1214
|
] }),
|
|
1105
|
-
showBack && !loading && /* @__PURE__ */
|
|
1215
|
+
showBack && !loading && /* @__PURE__ */ jsx6("p", { className: "fc-switch", children: /* @__PURE__ */ jsx6("button", { type: "button", className: "fc-link", onClick: () => setModalStep("method-select"), children: "Back" }) })
|
|
1106
1216
|
] });
|
|
1107
1217
|
}
|
|
1108
1218
|
|
|
1109
1219
|
// src/components/tabs/forgot-password.tsx
|
|
1110
1220
|
import { useState as useState4 } from "react";
|
|
1111
|
-
import { jsx as
|
|
1221
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1112
1222
|
function ForgotPasswordForm() {
|
|
1113
1223
|
const { forgotPassword, resetPassword, setModalStep } = useForgeConnect();
|
|
1114
1224
|
const [step, setStep] = useState4("email");
|
|
@@ -1144,24 +1254,24 @@ function ForgotPasswordForm() {
|
|
|
1144
1254
|
}
|
|
1145
1255
|
};
|
|
1146
1256
|
if (step === "done") {
|
|
1147
|
-
return /* @__PURE__ */
|
|
1148
|
-
/* @__PURE__ */
|
|
1149
|
-
/* @__PURE__ */
|
|
1150
|
-
/* @__PURE__ */
|
|
1257
|
+
return /* @__PURE__ */ jsxs6("div", { className: "fc-tab", children: [
|
|
1258
|
+
/* @__PURE__ */ jsx7("h3", { className: "fc-tab-title", children: "Password updated" }),
|
|
1259
|
+
/* @__PURE__ */ jsx7("p", { className: "fc-text", children: "Your password has been reset. You can now sign in." }),
|
|
1260
|
+
/* @__PURE__ */ jsx7("button", { type: "button", className: "fc-btn fc-btn-primary", onClick: () => setModalStep("email-login"), children: "Sign in" })
|
|
1151
1261
|
] });
|
|
1152
1262
|
}
|
|
1153
1263
|
if (step === "reset") {
|
|
1154
|
-
return /* @__PURE__ */
|
|
1155
|
-
/* @__PURE__ */
|
|
1156
|
-
/* @__PURE__ */
|
|
1264
|
+
return /* @__PURE__ */ jsxs6("div", { className: "fc-tab", children: [
|
|
1265
|
+
/* @__PURE__ */ jsx7("h3", { className: "fc-tab-title", children: "Set new password" }),
|
|
1266
|
+
/* @__PURE__ */ jsxs6("p", { className: "fc-text", children: [
|
|
1157
1267
|
"We sent a reset code to ",
|
|
1158
|
-
/* @__PURE__ */
|
|
1268
|
+
/* @__PURE__ */ jsx7("strong", { children: email }),
|
|
1159
1269
|
". Paste it below with your new password."
|
|
1160
1270
|
] }),
|
|
1161
|
-
/* @__PURE__ */
|
|
1162
|
-
/* @__PURE__ */
|
|
1271
|
+
/* @__PURE__ */ jsxs6("form", { onSubmit: handleReset, className: "fc-form", children: [
|
|
1272
|
+
/* @__PURE__ */ jsxs6("label", { className: "fc-label", children: [
|
|
1163
1273
|
"Reset code",
|
|
1164
|
-
/* @__PURE__ */
|
|
1274
|
+
/* @__PURE__ */ jsx7(
|
|
1165
1275
|
"input",
|
|
1166
1276
|
{
|
|
1167
1277
|
type: "text",
|
|
@@ -1174,9 +1284,9 @@ function ForgotPasswordForm() {
|
|
|
1174
1284
|
}
|
|
1175
1285
|
)
|
|
1176
1286
|
] }),
|
|
1177
|
-
/* @__PURE__ */
|
|
1287
|
+
/* @__PURE__ */ jsxs6("label", { className: "fc-label", children: [
|
|
1178
1288
|
"New password",
|
|
1179
|
-
/* @__PURE__ */
|
|
1289
|
+
/* @__PURE__ */ jsx7(
|
|
1180
1290
|
"input",
|
|
1181
1291
|
{
|
|
1182
1292
|
type: "password",
|
|
@@ -1190,19 +1300,19 @@ function ForgotPasswordForm() {
|
|
|
1190
1300
|
}
|
|
1191
1301
|
)
|
|
1192
1302
|
] }),
|
|
1193
|
-
error && /* @__PURE__ */
|
|
1194
|
-
/* @__PURE__ */
|
|
1303
|
+
error && /* @__PURE__ */ jsx7("p", { className: "fc-error", children: error }),
|
|
1304
|
+
/* @__PURE__ */ jsx7("button", { type: "submit", className: "fc-btn fc-btn-primary", disabled: loading, children: loading ? "Resetting..." : "Reset password" })
|
|
1195
1305
|
] }),
|
|
1196
|
-
/* @__PURE__ */
|
|
1306
|
+
/* @__PURE__ */ jsx7("p", { className: "fc-switch", children: /* @__PURE__ */ jsx7("button", { type: "button", className: "fc-link", onClick: () => setStep("email"), children: "Resend code" }) })
|
|
1197
1307
|
] });
|
|
1198
1308
|
}
|
|
1199
|
-
return /* @__PURE__ */
|
|
1200
|
-
/* @__PURE__ */
|
|
1201
|
-
/* @__PURE__ */
|
|
1202
|
-
/* @__PURE__ */
|
|
1203
|
-
/* @__PURE__ */
|
|
1309
|
+
return /* @__PURE__ */ jsxs6("div", { className: "fc-tab", children: [
|
|
1310
|
+
/* @__PURE__ */ jsx7("h3", { className: "fc-tab-title", children: "Reset your password" }),
|
|
1311
|
+
/* @__PURE__ */ jsx7("p", { className: "fc-text", children: "Enter your email and we'll send you a reset code." }),
|
|
1312
|
+
/* @__PURE__ */ jsxs6("form", { onSubmit: handleSendCode, className: "fc-form", children: [
|
|
1313
|
+
/* @__PURE__ */ jsxs6("label", { className: "fc-label", children: [
|
|
1204
1314
|
"Email",
|
|
1205
|
-
/* @__PURE__ */
|
|
1315
|
+
/* @__PURE__ */ jsx7(
|
|
1206
1316
|
"input",
|
|
1207
1317
|
{
|
|
1208
1318
|
type: "email",
|
|
@@ -1215,25 +1325,25 @@ function ForgotPasswordForm() {
|
|
|
1215
1325
|
}
|
|
1216
1326
|
)
|
|
1217
1327
|
] }),
|
|
1218
|
-
error && /* @__PURE__ */
|
|
1219
|
-
/* @__PURE__ */
|
|
1328
|
+
error && /* @__PURE__ */ jsx7("p", { className: "fc-error", children: error }),
|
|
1329
|
+
/* @__PURE__ */ jsx7("button", { type: "submit", className: "fc-btn fc-btn-primary", disabled: loading, children: loading ? "Sending..." : "Send reset code" })
|
|
1220
1330
|
] }),
|
|
1221
|
-
/* @__PURE__ */
|
|
1331
|
+
/* @__PURE__ */ jsx7("p", { className: "fc-switch", children: /* @__PURE__ */ jsx7("button", { type: "button", className: "fc-link", onClick: () => setModalStep("email-login"), children: "Back to sign in" }) })
|
|
1222
1332
|
] });
|
|
1223
1333
|
}
|
|
1224
1334
|
|
|
1225
1335
|
// src/components/tabs/verify-2fa.tsx
|
|
1226
|
-
import { useState as useState5, useRef as
|
|
1227
|
-
import { jsx as
|
|
1336
|
+
import { useState as useState5, useRef as useRef5, useEffect as useEffect4, useCallback as useCallback2 } from "react";
|
|
1337
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1228
1338
|
function Verify2FAForm() {
|
|
1229
1339
|
const { verify2FA, verifyRecoveryCode, setModalStep } = useForgeConnect();
|
|
1230
1340
|
const [code, setCode] = useState5("");
|
|
1231
1341
|
const [loading, setLoading] = useState5(false);
|
|
1232
1342
|
const [error, setError] = useState5("");
|
|
1233
1343
|
const [useRecovery, setUseRecovery] = useState5(false);
|
|
1234
|
-
const inputRef =
|
|
1235
|
-
const submittingRef =
|
|
1236
|
-
|
|
1344
|
+
const inputRef = useRef5(null);
|
|
1345
|
+
const submittingRef = useRef5(false);
|
|
1346
|
+
useEffect4(() => {
|
|
1237
1347
|
inputRef.current?.focus();
|
|
1238
1348
|
}, [useRecovery]);
|
|
1239
1349
|
const submitCode = useCallback2(async (codeValue, isRecovery) => {
|
|
@@ -1264,15 +1374,15 @@ function Verify2FAForm() {
|
|
|
1264
1374
|
submitCode(value, false);
|
|
1265
1375
|
}
|
|
1266
1376
|
};
|
|
1267
|
-
return /* @__PURE__ */
|
|
1268
|
-
/* @__PURE__ */
|
|
1269
|
-
/* @__PURE__ */
|
|
1377
|
+
return /* @__PURE__ */ jsxs7("div", { className: "fc-tab", children: [
|
|
1378
|
+
/* @__PURE__ */ jsxs7("button", { type: "button", className: "fc-back", onClick: () => setModalStep("method-select"), children: [
|
|
1379
|
+
/* @__PURE__ */ jsx8("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ jsx8("path", { d: "M10 12L6 8l4-4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }),
|
|
1270
1380
|
"Back"
|
|
1271
1381
|
] }),
|
|
1272
|
-
/* @__PURE__ */
|
|
1273
|
-
error && /* @__PURE__ */
|
|
1274
|
-
/* @__PURE__ */
|
|
1275
|
-
/* @__PURE__ */
|
|
1382
|
+
/* @__PURE__ */ jsx8("p", { className: "fc-account-section-desc", style: { marginTop: 8 }, children: useRecovery ? "Enter one of your recovery codes." : "Enter the 6-digit code from your authenticator app." }),
|
|
1383
|
+
error && /* @__PURE__ */ jsx8("p", { className: "fc-error", children: error }),
|
|
1384
|
+
/* @__PURE__ */ jsxs7("form", { onSubmit: handleSubmit, className: "fc-form", children: [
|
|
1385
|
+
/* @__PURE__ */ jsx8(
|
|
1276
1386
|
"input",
|
|
1277
1387
|
{
|
|
1278
1388
|
ref: inputRef,
|
|
@@ -1287,9 +1397,9 @@ function Verify2FAForm() {
|
|
|
1287
1397
|
style: useRecovery ? {} : { textAlign: "center", letterSpacing: "0.3em", fontSize: "1.25rem" }
|
|
1288
1398
|
}
|
|
1289
1399
|
),
|
|
1290
|
-
/* @__PURE__ */
|
|
1400
|
+
/* @__PURE__ */ jsx8("button", { type: "submit", className: "fc-btn fc-btn-primary", disabled: loading || !code.trim(), children: loading ? "Verifying..." : "Verify" })
|
|
1291
1401
|
] }),
|
|
1292
|
-
/* @__PURE__ */
|
|
1402
|
+
/* @__PURE__ */ jsx8(
|
|
1293
1403
|
"button",
|
|
1294
1404
|
{
|
|
1295
1405
|
type: "button",
|
|
@@ -1306,80 +1416,6 @@ function Verify2FAForm() {
|
|
|
1306
1416
|
] });
|
|
1307
1417
|
}
|
|
1308
1418
|
|
|
1309
|
-
// src/components/svg-icon.tsx
|
|
1310
|
-
import { useRef as useRef5, useEffect as useEffect4 } from "react";
|
|
1311
|
-
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
1312
|
-
function SvgIcon({ svg, className }) {
|
|
1313
|
-
const ref = useRef5(null);
|
|
1314
|
-
useEffect4(() => {
|
|
1315
|
-
if (!ref.current || !svg) return;
|
|
1316
|
-
try {
|
|
1317
|
-
const doc = new DOMParser().parseFromString(svg, "text/html");
|
|
1318
|
-
const svgEl = doc.body.querySelector("svg");
|
|
1319
|
-
if (!svgEl) {
|
|
1320
|
-
ref.current.textContent = "";
|
|
1321
|
-
return;
|
|
1322
|
-
}
|
|
1323
|
-
const dangerous = svgEl.querySelectorAll("script,iframe,object,embed,foreignObject");
|
|
1324
|
-
dangerous.forEach((el) => el.remove());
|
|
1325
|
-
const all = svgEl.querySelectorAll("*");
|
|
1326
|
-
all.forEach((el) => {
|
|
1327
|
-
for (const attr of Array.from(el.attributes)) {
|
|
1328
|
-
if (attr.name.startsWith("on")) {
|
|
1329
|
-
el.removeAttribute(attr.name);
|
|
1330
|
-
}
|
|
1331
|
-
}
|
|
1332
|
-
});
|
|
1333
|
-
ref.current.textContent = "";
|
|
1334
|
-
ref.current.appendChild(svgEl);
|
|
1335
|
-
} catch {
|
|
1336
|
-
ref.current.textContent = "";
|
|
1337
|
-
}
|
|
1338
|
-
}, [svg]);
|
|
1339
|
-
return /* @__PURE__ */ jsx7("span", { ref, className });
|
|
1340
|
-
}
|
|
1341
|
-
|
|
1342
|
-
// src/components/tabs/oauth-buttons.tsx
|
|
1343
|
-
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1344
|
-
var PROVIDER_INFO = {
|
|
1345
|
-
google: {
|
|
1346
|
-
label: "Google",
|
|
1347
|
-
icon: '<svg viewBox="0 0 24 24" width="20" height="20"><path d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92a5.06 5.06 0 0 1-2.2 3.32v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.1z" fill="#4285F4"/><path d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z" fill="#34A853"/><path d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z" fill="#FBBC05"/><path d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z" fill="#EA4335"/></svg>'
|
|
1348
|
-
},
|
|
1349
|
-
discord: {
|
|
1350
|
-
label: "Discord",
|
|
1351
|
-
icon: '<svg viewBox="0 0 24 24" width="20" height="20"><path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128c.126-.094.252-.192.372-.292a.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03z" fill="#5865F2"/></svg>'
|
|
1352
|
-
},
|
|
1353
|
-
twitter: {
|
|
1354
|
-
label: "Twitter",
|
|
1355
|
-
icon: '<svg viewBox="0 0 24 24" width="20" height="20"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" fill="currentColor"/></svg>'
|
|
1356
|
-
},
|
|
1357
|
-
apple: {
|
|
1358
|
-
label: "Apple",
|
|
1359
|
-
icon: '<svg viewBox="0 0 24 24" width="20" height="20"><path d="M17.05 20.28c-.98.95-2.05.88-3.08.4-1.09-.5-2.08-.52-3.23 0-1.44.64-2.2.45-3.06-.4C3.79 16.17 4.36 9.02 8.8 8.78c1.27.06 2.15.72 2.91.76.93-.19 1.82-.88 2.83-.8 1.21.1 2.12.58 2.72 1.49-2.46 1.48-1.88 4.73.52 5.64-.42 1.13-.98 2.24-1.73 3.41zM12.03 8.7c-.12-2.35 1.82-4.38 4.04-4.54.29 2.56-2.34 4.68-4.04 4.54z" fill="currentColor"/></svg>'
|
|
1360
|
-
},
|
|
1361
|
-
telegram: {
|
|
1362
|
-
label: "Telegram",
|
|
1363
|
-
icon: '<svg viewBox="0 0 24 24" width="20" height="20"><path d="M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.479.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z" fill="#2AABEE"/></svg>'
|
|
1364
|
-
}
|
|
1365
|
-
};
|
|
1366
|
-
function OAuthButton({ provider }) {
|
|
1367
|
-
const { loginWithOAuth } = useForgeConnect();
|
|
1368
|
-
const info = PROVIDER_INFO[provider];
|
|
1369
|
-
return /* @__PURE__ */ jsxs7(
|
|
1370
|
-
"button",
|
|
1371
|
-
{
|
|
1372
|
-
type: "button",
|
|
1373
|
-
className: "fc-btn fc-btn-oauth",
|
|
1374
|
-
onClick: () => loginWithOAuth(provider),
|
|
1375
|
-
children: [
|
|
1376
|
-
/* @__PURE__ */ jsx8(SvgIcon, { svg: info.icon, className: "fc-oauth-icon" }),
|
|
1377
|
-
/* @__PURE__ */ jsx8("span", { className: "fc-btn-name", children: info.label })
|
|
1378
|
-
]
|
|
1379
|
-
}
|
|
1380
|
-
);
|
|
1381
|
-
}
|
|
1382
|
-
|
|
1383
1419
|
// src/components/login-modal.tsx
|
|
1384
1420
|
import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1385
1421
|
function LoginModal() {
|
|
@@ -1434,7 +1470,8 @@ function LoginModal() {
|
|
|
1434
1470
|
config.appearance.termsUrl && /* @__PURE__ */ jsx9("a", { href: config.appearance.termsUrl, target: "_blank", rel: "noopener noreferrer", className: "fc-legal-link", children: "Terms" }),
|
|
1435
1471
|
config.appearance.termsUrl && config.appearance.privacyUrl && " and ",
|
|
1436
1472
|
config.appearance.privacyUrl && /* @__PURE__ */ jsx9("a", { href: config.appearance.privacyUrl, target: "_blank", rel: "noopener noreferrer", className: "fc-legal-link", children: "Privacy Policy" })
|
|
1437
|
-
] })
|
|
1473
|
+
] }),
|
|
1474
|
+
/* @__PURE__ */ jsx9(NomuPill, {})
|
|
1438
1475
|
] })
|
|
1439
1476
|
}
|
|
1440
1477
|
) });
|
|
@@ -1551,6 +1588,22 @@ function OAuthLoadingView() {
|
|
|
1551
1588
|
/* @__PURE__ */ jsx9("button", { type: "button", className: "fc-btn fc-btn-secondary", style: { marginTop: "16px" }, onClick: () => setModalStep("method-select"), children: "Cancel" })
|
|
1552
1589
|
] });
|
|
1553
1590
|
}
|
|
1591
|
+
var NOMU_LOGO = '<svg viewBox="0 0 466 115" fill="currentColor" xmlns="http://www.w3.org/2000/svg" aria-label="Nomu"><path d="M86.1037 1.64399C89.2226 2.96692 92.9067 6.05804 94.8954 8.90299C101.195 17.9195 103.263 31.5362 105.652 42.3487C108.921 57.1343 113.078 73.2835 111.843 88.981C111.25 96.5118 107.934 104.178 100.485 106.907C78.5857 114.928 68.4753 94.3605 55.5778 81.0755C54.0151 79.4657 49.9264 75.4498 48.017 74.7242C45.1699 73.6431 46.4243 77.2266 46.9038 78.6202C48.9075 84.4342 52.7842 89.1608 55.1111 94.4333C58.2322 101.506 56.3335 109.491 48.9353 112.563C38.6837 116.818 24.7051 108.932 18.1076 100.994C9.79754 90.9975 3.49328 72.2174 1.14497 59.3049C-1.5908 44.2668 -0.458383 24.9194 16.2003 18.5938C32.7091 12.3216 46.9723 35.7212 56.8964 45.2451C58.5169 46.8013 61.9677 50.9392 63.3912 46.949C64.6285 43.4833 63.6652 36.0102 63.4983 32.0543C62.9845 19.8418 61.3918 -1.3144 79.4334 0.0641835C81.3279 0.209749 84.3483 0.899043 86.1015 1.64399H86.1037Z"/><path d="M198.265 10.0303C208.463 15.8037 214.843 26.2244 217.82 37.2467C220.237 46.1968 221.048 56.7482 219.807 66.1799C216.628 90.3223 200.149 109.849 174.493 110.988C157.695 111.733 139.746 105.682 131.472 90.1896C118.984 66.8071 137.597 43.8678 152.329 27.1128C164.501 13.2691 178.368 -1.23604 198.265 10.0303ZM175.364 41.9176C169.771 38.1072 164.25 44.1996 162.46 49.0803C159.339 57.5916 160.988 72.0346 172.766 71.1591C180.16 70.609 181.427 61.1108 181.02 55.2047C180.752 51.3451 178.7 44.1867 175.364 41.9155V41.9176Z"/><path d="M324.975 3.83292C329.706 5.77236 335.978 13.6051 338.509 17.8479C348.347 34.3438 351.002 53.6547 350.321 73.0085C349.884 85.4008 348.086 102.122 337.415 109.993C321.938 121.407 304.25 107.993 308.199 89.9711C308.681 87.7705 309.725 85.6213 310.52 83.5555C311.913 79.9293 311.83 74.2415 310.92 70.2556C310.903 70.1807 310.614 69.4079 310.483 68.9476C309.62 65.8737 307.548 61.6908 303.712 63.5468C302.409 64.1783 300.839 66.2162 299.022 67.096C292.491 70.2577 283.616 65.5697 280.37 59.4559C279.444 57.707 277.958 52.7728 276.322 51.9444C274.342 50.9425 273.617 52.8948 273.09 54.4382C271.587 58.8437 271.701 66.5394 273.096 71.2232C273.957 74.1088 275.809 76.866 276.92 79.6103C281.115 89.9733 285.647 107.621 270.934 111.791C262.391 114.212 256.003 109.961 250.756 103.888C231.165 81.2072 230.598 47.9049 244.878 21.7289C250.014 12.3142 256.371 6.06777 268.012 6.30967C275.396 6.4638 279.829 10.469 283.241 16.5442C285.532 20.62 287.7 25.1582 290.905 28.7995C293.204 31.4111 296.462 34.0398 299.778 31.2077C303.727 27.8362 305.846 18.0876 308.505 13.2219C311.802 7.18948 317.203 0.649749 324.973 3.83292H324.975Z"/><path d="M452.977 13.4681C459.921 19.2693 464.095 29.0907 465.288 37.8695C468.466 61.282 454.854 98.4611 432.55 109.468C421.31 115.015 406.192 112.904 394.569 109.445C375.919 103.894 364.978 87.4109 363.803 68.2841C362.775 51.5612 371.925 30.2787 381.817 17.15C388.977 7.64763 404.21 11.5072 408.836 21.3243C411.705 27.4124 409.059 30.8824 406.488 36.0436C430.727 62.0334 432.463 57.1377 431.208 47.5453C429.772 36.5723 421.213 13.8256 437.17 9.58065C442.973 8.03724 448.492 9.72193 452.977 13.4681Z"/></svg>';
|
|
1592
|
+
function NomuPill() {
|
|
1593
|
+
return /* @__PURE__ */ jsx9("div", { className: "fc-nomu-wrap", children: /* @__PURE__ */ jsxs8(
|
|
1594
|
+
"a",
|
|
1595
|
+
{
|
|
1596
|
+
href: "https://www.nomu.dev/",
|
|
1597
|
+
target: "_blank",
|
|
1598
|
+
rel: "noopener noreferrer",
|
|
1599
|
+
className: "fc-nomu-pill",
|
|
1600
|
+
children: [
|
|
1601
|
+
/* @__PURE__ */ jsx9("span", { children: "Powered by" }),
|
|
1602
|
+
/* @__PURE__ */ jsx9(SvgIcon, { svg: NOMU_LOGO, className: "fc-nomu-logo" })
|
|
1603
|
+
]
|
|
1604
|
+
}
|
|
1605
|
+
) });
|
|
1606
|
+
}
|
|
1554
1607
|
function SuccessView() {
|
|
1555
1608
|
return /* @__PURE__ */ jsxs8("div", { className: "fc-success", children: [
|
|
1556
1609
|
/* @__PURE__ */ jsx9("div", { className: "fc-success-icon", children: /* @__PURE__ */ jsxs8("svg", { viewBox: "0 0 52 52", className: "fc-success-check", children: [
|
|
@@ -3769,6 +3822,7 @@ function SuccessView2() {
|
|
|
3769
3822
|
|
|
3770
3823
|
// src/provider.tsx
|
|
3771
3824
|
import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
3825
|
+
var oauthExchangeCache = /* @__PURE__ */ new Map();
|
|
3772
3826
|
function ForgeConnectProvider({ config, children, onLogin, onLogout, walletAdapter }) {
|
|
3773
3827
|
const [auth, setAuth] = useState16({
|
|
3774
3828
|
status: "loading",
|
|
@@ -3827,42 +3881,81 @@ function ForgeConnectProvider({ config, children, onLogin, onLogout, walletAdapt
|
|
|
3827
3881
|
return;
|
|
3828
3882
|
}
|
|
3829
3883
|
const authCode = params.get("fc_code");
|
|
3830
|
-
if (authCode
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3884
|
+
if (authCode) {
|
|
3885
|
+
try {
|
|
3886
|
+
localStorage.setItem("fc_oauth_code_pending", authCode);
|
|
3887
|
+
} catch {
|
|
3888
|
+
}
|
|
3889
|
+
if (window.opener) {
|
|
3890
|
+
window.opener.postMessage(
|
|
3891
|
+
{ type: "fc_oauth_code", code: authCode },
|
|
3892
|
+
window.location.origin
|
|
3893
|
+
);
|
|
3894
|
+
}
|
|
3835
3895
|
window.close();
|
|
3836
3896
|
return;
|
|
3837
3897
|
}
|
|
3838
3898
|
}
|
|
3839
|
-
const
|
|
3899
|
+
const handleCode = async (code) => {
|
|
3900
|
+
let exchangePromise = oauthExchangeCache.get(code);
|
|
3901
|
+
if (!exchangePromise) {
|
|
3902
|
+
try {
|
|
3903
|
+
localStorage.removeItem("fc_oauth_code_pending");
|
|
3904
|
+
} catch {
|
|
3905
|
+
}
|
|
3906
|
+
exchangePromise = (async () => {
|
|
3907
|
+
try {
|
|
3908
|
+
const result = await api.exchangeOAuthCode(code);
|
|
3909
|
+
if (result.requires2FA && result.challengeToken) {
|
|
3910
|
+
return { kind: "requires2FA", challengeToken: result.challengeToken };
|
|
3911
|
+
}
|
|
3912
|
+
const token = result.accessToken;
|
|
3913
|
+
if (!token) return null;
|
|
3914
|
+
const user = await api.getMe(token);
|
|
3915
|
+
return { kind: "authenticated", accessToken: token, user };
|
|
3916
|
+
} catch {
|
|
3917
|
+
return null;
|
|
3918
|
+
}
|
|
3919
|
+
})();
|
|
3920
|
+
oauthExchangeCache.set(code, exchangePromise);
|
|
3921
|
+
}
|
|
3922
|
+
const outcome = await exchangePromise;
|
|
3923
|
+
if (!outcome) return;
|
|
3924
|
+
if (outcome.kind === "requires2FA") {
|
|
3925
|
+
setChallengeToken(outcome.challengeToken);
|
|
3926
|
+
setModal({ isOpen: true, step: "verify-2fa" });
|
|
3927
|
+
return;
|
|
3928
|
+
}
|
|
3929
|
+
setModal({ isOpen: true, step: "success" });
|
|
3930
|
+
setAuth({ status: "authenticated", user: outcome.user, accessToken: outcome.accessToken });
|
|
3931
|
+
scheduleRefresh(outcome.accessToken);
|
|
3932
|
+
onLogin?.(outcome.user);
|
|
3933
|
+
setTimeout(() => {
|
|
3934
|
+
setModal({ isOpen: false, step: "method-select" });
|
|
3935
|
+
}, 1500);
|
|
3936
|
+
};
|
|
3937
|
+
const handleMessage = (event) => {
|
|
3840
3938
|
if (event.origin !== window.location.origin) return;
|
|
3841
3939
|
if (event.data?.type !== "fc_oauth_code") return;
|
|
3842
3940
|
const code = event.data.code;
|
|
3843
3941
|
if (!code) return;
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
return;
|
|
3850
|
-
}
|
|
3851
|
-
const token = result.accessToken;
|
|
3852
|
-
if (!token) return;
|
|
3853
|
-
setModal({ isOpen: true, step: "success" });
|
|
3854
|
-
const user = await api.getMe(token);
|
|
3855
|
-
setAuth({ status: "authenticated", user, accessToken: token });
|
|
3856
|
-
scheduleRefresh(token);
|
|
3857
|
-
onLogin?.(user);
|
|
3858
|
-
setTimeout(() => {
|
|
3859
|
-
setModal({ isOpen: false, step: "method-select" });
|
|
3860
|
-
}, 1500);
|
|
3861
|
-
} catch {
|
|
3862
|
-
}
|
|
3942
|
+
void handleCode(code);
|
|
3943
|
+
};
|
|
3944
|
+
const handleStorage = (event) => {
|
|
3945
|
+
if (event.key !== "fc_oauth_code_pending" || !event.newValue) return;
|
|
3946
|
+
void handleCode(event.newValue);
|
|
3863
3947
|
};
|
|
3948
|
+
try {
|
|
3949
|
+
const pending = localStorage.getItem("fc_oauth_code_pending");
|
|
3950
|
+
if (pending) void handleCode(pending);
|
|
3951
|
+
} catch {
|
|
3952
|
+
}
|
|
3864
3953
|
window.addEventListener("message", handleMessage);
|
|
3865
|
-
|
|
3954
|
+
window.addEventListener("storage", handleStorage);
|
|
3955
|
+
return () => {
|
|
3956
|
+
window.removeEventListener("message", handleMessage);
|
|
3957
|
+
window.removeEventListener("storage", handleStorage);
|
|
3958
|
+
};
|
|
3866
3959
|
}, [api, config.apiUrl, scheduleRefresh, onLogin]);
|
|
3867
3960
|
useEffect12(() => {
|
|
3868
3961
|
if (config.loginMethods && config.loginMethods.length > 0) {
|