cilantro-react 0.1.5 → 0.1.7
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/README.md +1063 -594
- package/dist/AuthGuard-siMJeYPD.d.mts +42 -0
- package/dist/AuthGuard-siMJeYPD.d.ts +42 -0
- package/dist/index.d.mts +134 -23
- package/dist/index.d.ts +134 -23
- package/dist/index.js +634 -273
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +611 -255
- package/dist/index.mjs.map +1 -1
- package/dist/next.d.mts +19 -0
- package/dist/next.d.ts +19 -0
- package/dist/next.js +494 -0
- package/dist/next.js.map +1 -0
- package/dist/next.mjs +465 -0
- package/dist/next.mjs.map +1 -0
- package/package.json +10 -3
package/dist/index.mjs
CHANGED
|
@@ -231,6 +231,14 @@ function normalizeWallet(dto) {
|
|
|
231
231
|
active: w.isActive
|
|
232
232
|
};
|
|
233
233
|
}
|
|
234
|
+
function getWalletId(wallet) {
|
|
235
|
+
if (!wallet) return "";
|
|
236
|
+
return wallet.id ?? wallet.walletId ?? "";
|
|
237
|
+
}
|
|
238
|
+
function getWalletAddress(wallet) {
|
|
239
|
+
if (!wallet) return "";
|
|
240
|
+
return wallet.address ?? wallet.walletAddress ?? "";
|
|
241
|
+
}
|
|
234
242
|
|
|
235
243
|
// src/context/CilantroContext.tsx
|
|
236
244
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -238,6 +246,17 @@ var DEFAULT_BASE_URL = "https://api.cilantro.gg";
|
|
|
238
246
|
var DEFAULT_JWT_STORAGE_KEY = "cilantro_jwt";
|
|
239
247
|
var DEFAULT_WALLET_STORAGE_KEY = "cilantro_selected_wallet_id";
|
|
240
248
|
var CilantroContext = createContext(void 0);
|
|
249
|
+
var DEFAULT_JWT_COOKIE_NAME = "cilantro_jwt";
|
|
250
|
+
function setJwtCookie(name, token) {
|
|
251
|
+
if (typeof document === "undefined") return;
|
|
252
|
+
const value = token ?? "";
|
|
253
|
+
if (!value) {
|
|
254
|
+
document.cookie = `${name}=; path=/; SameSite=Lax; max-age=0`;
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
const maxAge = 60 * 60 * 24 * 7;
|
|
258
|
+
document.cookie = `${name}=${encodeURIComponent(value)}; path=/; SameSite=Lax; max-age=${maxAge}`;
|
|
259
|
+
}
|
|
241
260
|
function CilantroContextProvider({
|
|
242
261
|
children,
|
|
243
262
|
apiKey,
|
|
@@ -245,6 +264,8 @@ function CilantroContextProvider({
|
|
|
245
264
|
storageAdapter = null,
|
|
246
265
|
jwtStorageKey = DEFAULT_JWT_STORAGE_KEY,
|
|
247
266
|
walletStorageKey = DEFAULT_WALLET_STORAGE_KEY,
|
|
267
|
+
syncJwtToCookie = false,
|
|
268
|
+
jwtCookieName = DEFAULT_JWT_COOKIE_NAME,
|
|
248
269
|
onLoginSuccess,
|
|
249
270
|
onLogout,
|
|
250
271
|
onRegisterSuccess,
|
|
@@ -300,6 +321,11 @@ function CilantroContextProvider({
|
|
|
300
321
|
}
|
|
301
322
|
setAuthLoading(false);
|
|
302
323
|
}, [apiKey, baseURL, jwtStorageKey]);
|
|
324
|
+
useEffect(() => {
|
|
325
|
+
if (syncJwtToCookie && typeof document !== "undefined") {
|
|
326
|
+
setJwtCookie(jwtCookieName, jwt);
|
|
327
|
+
}
|
|
328
|
+
}, [jwt, syncJwtToCookie, jwtCookieName]);
|
|
303
329
|
const login = useCallback(
|
|
304
330
|
async (params) => {
|
|
305
331
|
const result = await cilantroLogin(params);
|
|
@@ -311,6 +337,7 @@ function CilantroContextProvider({
|
|
|
311
337
|
setSdkAuth(token);
|
|
312
338
|
if (typeof window !== "undefined") {
|
|
313
339
|
localStorage.setItem(jwtStorageKey, token);
|
|
340
|
+
if (syncJwtToCookie) setJwtCookie(jwtCookieName, token);
|
|
314
341
|
}
|
|
315
342
|
if (data?.user && typeof data.user === "object") {
|
|
316
343
|
const u = data.user;
|
|
@@ -333,7 +360,7 @@ function CilantroContextProvider({
|
|
|
333
360
|
}
|
|
334
361
|
onLoginSuccess?.();
|
|
335
362
|
},
|
|
336
|
-
[jwtStorageKey, onLoginSuccess]
|
|
363
|
+
[jwtStorageKey, jwtCookieName, syncJwtToCookie, onLoginSuccess]
|
|
337
364
|
);
|
|
338
365
|
const logout = useCallback(() => {
|
|
339
366
|
setUser(null);
|
|
@@ -341,6 +368,7 @@ function CilantroContextProvider({
|
|
|
341
368
|
clearAuth();
|
|
342
369
|
if (typeof window !== "undefined") {
|
|
343
370
|
localStorage.removeItem(jwtStorageKey);
|
|
371
|
+
if (syncJwtToCookie) setJwtCookie(jwtCookieName, null);
|
|
344
372
|
const keys = Object.keys(localStorage);
|
|
345
373
|
keys.forEach((key) => {
|
|
346
374
|
if (key.startsWith("delegated-key-")) localStorage.removeItem(key);
|
|
@@ -348,7 +376,7 @@ function CilantroContextProvider({
|
|
|
348
376
|
}
|
|
349
377
|
setSdkAuth(null);
|
|
350
378
|
onLogout?.();
|
|
351
|
-
}, [jwtStorageKey, onLogout]);
|
|
379
|
+
}, [jwtStorageKey, jwtCookieName, syncJwtToCookie, onLogout]);
|
|
352
380
|
const register = useCallback(
|
|
353
381
|
async (username, email, password, isActive = true) => {
|
|
354
382
|
setSdkAuth(null);
|
|
@@ -367,6 +395,7 @@ function CilantroContextProvider({
|
|
|
367
395
|
clearAuth();
|
|
368
396
|
if (typeof window !== "undefined") {
|
|
369
397
|
localStorage.removeItem(jwtStorageKey);
|
|
398
|
+
if (syncJwtToCookie) setJwtCookie(jwtCookieName, null);
|
|
370
399
|
const keys = Object.keys(localStorage);
|
|
371
400
|
keys.forEach((key) => {
|
|
372
401
|
if (key.startsWith("delegated-key-")) localStorage.removeItem(key);
|
|
@@ -374,7 +403,7 @@ function CilantroContextProvider({
|
|
|
374
403
|
}
|
|
375
404
|
setSdkAuth(null);
|
|
376
405
|
onSessionExpired?.();
|
|
377
|
-
}, [jwtStorageKey, onSessionExpired]);
|
|
406
|
+
}, [jwtStorageKey, jwtCookieName, syncJwtToCookie, onSessionExpired]);
|
|
378
407
|
const loadWallets = useCallback(async () => {
|
|
379
408
|
if (!jwt) return;
|
|
380
409
|
setWalletsLoading(true);
|
|
@@ -513,6 +542,8 @@ function CilantroProvider({
|
|
|
513
542
|
apiUrl: apiUrl2,
|
|
514
543
|
jwtStorageKey,
|
|
515
544
|
walletStorageKey,
|
|
545
|
+
syncJwtToCookie,
|
|
546
|
+
jwtCookieName,
|
|
516
547
|
onLoginSuccess,
|
|
517
548
|
onLogout,
|
|
518
549
|
onRegisterSuccess,
|
|
@@ -535,6 +566,8 @@ function CilantroProvider({
|
|
|
535
566
|
storageAdapter: storageAdapter ?? void 0,
|
|
536
567
|
jwtStorageKey,
|
|
537
568
|
walletStorageKey,
|
|
569
|
+
syncJwtToCookie,
|
|
570
|
+
jwtCookieName,
|
|
538
571
|
onLoginSuccess,
|
|
539
572
|
onLogout,
|
|
540
573
|
onRegisterSuccess,
|
|
@@ -549,6 +582,7 @@ function useCilantroAuth() {
|
|
|
549
582
|
const ctx = useCilantroContext();
|
|
550
583
|
return {
|
|
551
584
|
user: ctx.user,
|
|
585
|
+
jwt: ctx.jwt,
|
|
552
586
|
token: ctx.jwt,
|
|
553
587
|
isAuthenticated: ctx.isAuthenticated,
|
|
554
588
|
login: (usernameOrEmail, password) => ctx.login({ usernameOrEmail, password }),
|
|
@@ -562,8 +596,10 @@ function useCilantroAuth() {
|
|
|
562
596
|
// src/providers/WalletProvider.tsx
|
|
563
597
|
function useWallets() {
|
|
564
598
|
const ctx = useCilantroContext();
|
|
599
|
+
const wallet = ctx.wallet;
|
|
565
600
|
return {
|
|
566
|
-
|
|
601
|
+
wallet,
|
|
602
|
+
selectedWallet: wallet,
|
|
567
603
|
wallets: ctx.wallets,
|
|
568
604
|
selectWallet: ctx.selectWallet,
|
|
569
605
|
refreshWallets: ctx.refreshWallets,
|
|
@@ -594,37 +630,83 @@ function useAuth() {
|
|
|
594
630
|
return {
|
|
595
631
|
user: ctx.user,
|
|
596
632
|
jwt: ctx.jwt,
|
|
633
|
+
token: ctx.jwt,
|
|
597
634
|
isLoading: ctx.isLoading,
|
|
598
635
|
isAuthenticated: ctx.isAuthenticated,
|
|
599
636
|
login: ctx.login,
|
|
600
|
-
|
|
637
|
+
register: ctx.register,
|
|
638
|
+
logout: ctx.logout,
|
|
639
|
+
clearSessionDueToAuthError: ctx.clearSessionDueToAuthError
|
|
601
640
|
};
|
|
602
641
|
}
|
|
603
642
|
|
|
643
|
+
// src/hooks/useReturnUrl.ts
|
|
644
|
+
import { useCallback as useCallback2, useMemo as useMemo2 } from "react";
|
|
645
|
+
function useReturnUrl(options = {}) {
|
|
646
|
+
const {
|
|
647
|
+
param = "returnUrl",
|
|
648
|
+
defaultPath = "/",
|
|
649
|
+
allowRelativeOnly = true
|
|
650
|
+
} = options;
|
|
651
|
+
const rawReturnUrl = useMemo2(() => {
|
|
652
|
+
if (typeof window === "undefined") return null;
|
|
653
|
+
const params = new URLSearchParams(window.location.search);
|
|
654
|
+
return params.get(param);
|
|
655
|
+
}, [param]);
|
|
656
|
+
const returnPath = useMemo2(() => {
|
|
657
|
+
if (!rawReturnUrl) return defaultPath;
|
|
658
|
+
if (allowRelativeOnly) {
|
|
659
|
+
const trimmed = rawReturnUrl.trim();
|
|
660
|
+
if (trimmed.startsWith("//") || /^https?:\/\//i.test(trimmed)) {
|
|
661
|
+
return defaultPath;
|
|
662
|
+
}
|
|
663
|
+
if (trimmed.startsWith("/")) return trimmed;
|
|
664
|
+
return `/${trimmed}`;
|
|
665
|
+
}
|
|
666
|
+
return rawReturnUrl;
|
|
667
|
+
}, [rawReturnUrl, defaultPath, allowRelativeOnly]);
|
|
668
|
+
const redirect = useCallback2(
|
|
669
|
+
(customRedirect) => {
|
|
670
|
+
const path = returnPath;
|
|
671
|
+
if (customRedirect) {
|
|
672
|
+
customRedirect(path);
|
|
673
|
+
} else if (typeof window !== "undefined") {
|
|
674
|
+
window.location.href = path;
|
|
675
|
+
}
|
|
676
|
+
},
|
|
677
|
+
[returnPath]
|
|
678
|
+
);
|
|
679
|
+
return { returnPath, redirect, rawReturnUrl };
|
|
680
|
+
}
|
|
681
|
+
|
|
604
682
|
// src/hooks/useWallet.ts
|
|
605
|
-
import { useMemo as
|
|
683
|
+
import { useMemo as useMemo3 } from "react";
|
|
606
684
|
function useWallet(_walletId) {
|
|
607
685
|
const ctx = useCilantroContext();
|
|
608
|
-
return
|
|
686
|
+
return useMemo3(
|
|
609
687
|
() => ({
|
|
610
688
|
wallet: ctx.wallet,
|
|
611
689
|
wallets: ctx.wallets,
|
|
612
690
|
createWallet: ctx.createWallet,
|
|
613
691
|
selectWallet: ctx.selectWallet,
|
|
614
|
-
|
|
692
|
+
refreshWallets: ctx.refreshWallets,
|
|
693
|
+
isLoading: ctx.walletsLoading,
|
|
694
|
+
error: ctx.walletError
|
|
615
695
|
}),
|
|
616
696
|
[
|
|
617
697
|
ctx.wallet,
|
|
618
698
|
ctx.wallets,
|
|
619
699
|
ctx.createWallet,
|
|
620
700
|
ctx.selectWallet,
|
|
621
|
-
ctx.
|
|
701
|
+
ctx.refreshWallets,
|
|
702
|
+
ctx.walletsLoading,
|
|
703
|
+
ctx.walletError
|
|
622
704
|
]
|
|
623
705
|
);
|
|
624
706
|
}
|
|
625
707
|
|
|
626
708
|
// src/hooks/useSigners.ts
|
|
627
|
-
import { useState as useState2, useEffect as useEffect3, useCallback as
|
|
709
|
+
import { useState as useState2, useEffect as useEffect3, useCallback as useCallback3 } from "react";
|
|
628
710
|
|
|
629
711
|
// src/core/signer-helpers.ts
|
|
630
712
|
import { getSigners, parseSignerResponse } from "cilantro-sdk/helpers";
|
|
@@ -835,7 +917,7 @@ function useSigners(walletIdOrOptions) {
|
|
|
835
917
|
const [signers, setSigners] = useState2([]);
|
|
836
918
|
const [isLoading, setIsLoading] = useState2(false);
|
|
837
919
|
const [error, setError] = useState2(null);
|
|
838
|
-
const load =
|
|
920
|
+
const load = useCallback3(
|
|
839
921
|
async (walletId) => {
|
|
840
922
|
if (!walletId) {
|
|
841
923
|
setSigners([]);
|
|
@@ -865,11 +947,11 @@ function useSigners(walletIdOrOptions) {
|
|
|
865
947
|
setError(null);
|
|
866
948
|
}
|
|
867
949
|
}, [walletIdOption, load]);
|
|
868
|
-
const refresh =
|
|
950
|
+
const refresh = useCallback3(async () => {
|
|
869
951
|
const id = walletIdOption ?? void 0;
|
|
870
952
|
if (id) await load(id);
|
|
871
953
|
}, [walletIdOption, load]);
|
|
872
|
-
const createEmailSigner =
|
|
954
|
+
const createEmailSigner = useCallback3(
|
|
873
955
|
async (params) => {
|
|
874
956
|
const walletId = walletIdOption ?? void 0;
|
|
875
957
|
if (!walletId) throw new Error("walletId is required");
|
|
@@ -880,7 +962,7 @@ function useSigners(walletIdOrOptions) {
|
|
|
880
962
|
},
|
|
881
963
|
[walletIdOption, jwt, refresh]
|
|
882
964
|
);
|
|
883
|
-
const createPhoneSigner =
|
|
965
|
+
const createPhoneSigner = useCallback3(
|
|
884
966
|
async (params) => {
|
|
885
967
|
const walletId = walletIdOption ?? void 0;
|
|
886
968
|
if (!walletId) throw new Error("walletId is required");
|
|
@@ -891,7 +973,7 @@ function useSigners(walletIdOrOptions) {
|
|
|
891
973
|
},
|
|
892
974
|
[walletIdOption, jwt, refresh]
|
|
893
975
|
);
|
|
894
|
-
const revokeSigner =
|
|
976
|
+
const revokeSigner = useCallback3(
|
|
895
977
|
async (signerId) => {
|
|
896
978
|
const walletId = walletIdOption ?? void 0;
|
|
897
979
|
if (!walletId) throw new Error("walletId is required");
|
|
@@ -913,7 +995,7 @@ function useSigners(walletIdOrOptions) {
|
|
|
913
995
|
}
|
|
914
996
|
|
|
915
997
|
// src/hooks/usePasskey.ts
|
|
916
|
-
import { useState as useState3, useCallback as
|
|
998
|
+
import { useState as useState3, useCallback as useCallback4 } from "react";
|
|
917
999
|
import { isWebAuthnSupported as isWebAuthnSupported2 } from "cilantro-sdk/helpers";
|
|
918
1000
|
import { startPasskeyAuthentication as startPasskeyAuthentication2 } from "cilantro-sdk/wallet";
|
|
919
1001
|
import { authenticateWithPasskey as authenticateWithPasskey2, formatAuthenticationResponse as formatAuthenticationResponse2 } from "cilantro-sdk/helpers";
|
|
@@ -921,7 +1003,7 @@ function usePasskey(walletId) {
|
|
|
921
1003
|
const { jwt } = useCilantroContext();
|
|
922
1004
|
const [isLoading, setIsLoading] = useState3(false);
|
|
923
1005
|
const isSupported = typeof window !== "undefined" && isWebAuthnSupported2();
|
|
924
|
-
const register =
|
|
1006
|
+
const register = useCallback4(async () => {
|
|
925
1007
|
if (!walletId) throw new Error("walletId is required");
|
|
926
1008
|
if (!isSupported) throw new Error("WebAuthn is not supported in this browser");
|
|
927
1009
|
setIsLoading(true);
|
|
@@ -932,7 +1014,7 @@ function usePasskey(walletId) {
|
|
|
932
1014
|
setIsLoading(false);
|
|
933
1015
|
}
|
|
934
1016
|
}, [walletId, isSupported]);
|
|
935
|
-
const authenticate =
|
|
1017
|
+
const authenticate = useCallback4(
|
|
936
1018
|
async (signerId) => {
|
|
937
1019
|
if (!walletId) throw new Error("walletId is required");
|
|
938
1020
|
if (!isSupported) throw new Error("WebAuthn is not supported in this browser");
|
|
@@ -962,7 +1044,7 @@ function usePasskey(walletId) {
|
|
|
962
1044
|
}
|
|
963
1045
|
|
|
964
1046
|
// src/hooks/useExternalWallet.ts
|
|
965
|
-
import { useState as useState4, useCallback as
|
|
1047
|
+
import { useState as useState4, useCallback as useCallback5, useEffect as useEffect4 } from "react";
|
|
966
1048
|
function getDetectedWallets() {
|
|
967
1049
|
if (typeof window === "undefined") return [];
|
|
968
1050
|
const list = [];
|
|
@@ -990,13 +1072,13 @@ function useExternalWallet() {
|
|
|
990
1072
|
useEffect4(() => {
|
|
991
1073
|
setWallets(getDetectedWallets());
|
|
992
1074
|
}, []);
|
|
993
|
-
const connect =
|
|
1075
|
+
const connect = useCallback5(async (wallet) => {
|
|
994
1076
|
const res = await wallet.connect();
|
|
995
1077
|
const publicKey = res.publicKey.toString();
|
|
996
1078
|
setConnectedWallet(wallet);
|
|
997
1079
|
return publicKey;
|
|
998
1080
|
}, []);
|
|
999
|
-
const disconnect =
|
|
1081
|
+
const disconnect = useCallback5(async () => {
|
|
1000
1082
|
if (connectedWallet?.disconnect) {
|
|
1001
1083
|
await connectedWallet.disconnect();
|
|
1002
1084
|
}
|
|
@@ -1006,13 +1088,13 @@ function useExternalWallet() {
|
|
|
1006
1088
|
}
|
|
1007
1089
|
|
|
1008
1090
|
// src/hooks/useSendTransaction.ts
|
|
1009
|
-
import { useState as useState5, useCallback as
|
|
1091
|
+
import { useState as useState5, useCallback as useCallback6 } from "react";
|
|
1010
1092
|
import { sendSOL as sendSOLApi, sendSPL as sendSPLApi } from "cilantro-sdk/wallet";
|
|
1011
1093
|
function useSendTransaction(walletId, _signerId, _signerType) {
|
|
1012
1094
|
const { jwt } = useCilantroContext();
|
|
1013
1095
|
const [isPending, setIsPending] = useState5(false);
|
|
1014
1096
|
const [error, setError] = useState5(null);
|
|
1015
|
-
const sendSOL =
|
|
1097
|
+
const sendSOL = useCallback6(
|
|
1016
1098
|
async (params) => {
|
|
1017
1099
|
if (!walletId) throw new Error("walletId is required");
|
|
1018
1100
|
setError(null);
|
|
@@ -1039,7 +1121,7 @@ function useSendTransaction(walletId, _signerId, _signerType) {
|
|
|
1039
1121
|
},
|
|
1040
1122
|
[walletId, jwt]
|
|
1041
1123
|
);
|
|
1042
|
-
const sendSPL =
|
|
1124
|
+
const sendSPL = useCallback6(
|
|
1043
1125
|
async (params) => {
|
|
1044
1126
|
if (!walletId) throw new Error("walletId is required");
|
|
1045
1127
|
setError(null);
|
|
@@ -1201,21 +1283,33 @@ function LoginForm({
|
|
|
1201
1283
|
style,
|
|
1202
1284
|
onSuccess,
|
|
1203
1285
|
onError,
|
|
1286
|
+
redirectAfterSuccess,
|
|
1287
|
+
onRedirect,
|
|
1288
|
+
returnUrlParam = "returnUrl",
|
|
1204
1289
|
submitLabel = "Sign in",
|
|
1205
1290
|
title = "Sign in",
|
|
1206
1291
|
description,
|
|
1207
1292
|
renderSwitchToRegister
|
|
1208
1293
|
}) {
|
|
1209
1294
|
const { login, isLoading } = useCilantroAuth();
|
|
1295
|
+
const { returnPath } = useReturnUrl({ param: returnUrlParam, defaultPath: "/" });
|
|
1210
1296
|
const [usernameOrEmail, setUsernameOrEmail] = useState6("");
|
|
1211
1297
|
const [password, setPassword] = useState6("");
|
|
1212
1298
|
const [error, setError] = useState6(null);
|
|
1299
|
+
const pathToRedirect = redirectAfterSuccess ?? returnPath;
|
|
1213
1300
|
const handleSubmit = async (e) => {
|
|
1214
1301
|
e.preventDefault();
|
|
1215
1302
|
setError(null);
|
|
1216
1303
|
try {
|
|
1217
1304
|
await login(usernameOrEmail.trim(), password);
|
|
1218
1305
|
onSuccess?.();
|
|
1306
|
+
if (pathToRedirect) {
|
|
1307
|
+
if (onRedirect) {
|
|
1308
|
+
onRedirect(pathToRedirect);
|
|
1309
|
+
} else if (typeof window !== "undefined") {
|
|
1310
|
+
window.location.href = pathToRedirect;
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1219
1313
|
} catch (err) {
|
|
1220
1314
|
const message = err instanceof Error ? err.message : String(err);
|
|
1221
1315
|
setError(message);
|
|
@@ -1288,16 +1382,142 @@ function LoginForm({
|
|
|
1288
1382
|
] });
|
|
1289
1383
|
}
|
|
1290
1384
|
|
|
1291
|
-
// src/components/auth/
|
|
1385
|
+
// src/components/auth/RegisterForm.tsx
|
|
1292
1386
|
import { useState as useState7 } from "react";
|
|
1387
|
+
import { jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1388
|
+
function RegisterForm({
|
|
1389
|
+
className,
|
|
1390
|
+
classNames,
|
|
1391
|
+
style,
|
|
1392
|
+
onSuccess,
|
|
1393
|
+
onError,
|
|
1394
|
+
redirectAfterSuccess,
|
|
1395
|
+
onRedirect,
|
|
1396
|
+
returnUrlParam = "returnUrl",
|
|
1397
|
+
submitLabel = "Create account",
|
|
1398
|
+
title = "Create account",
|
|
1399
|
+
description,
|
|
1400
|
+
renderSwitchToLogin
|
|
1401
|
+
}) {
|
|
1402
|
+
const { register, isLoading } = useAuth();
|
|
1403
|
+
const { returnPath } = useReturnUrl({ param: returnUrlParam, defaultPath: "/" });
|
|
1404
|
+
const [username, setUsername] = useState7("");
|
|
1405
|
+
const [email, setEmail] = useState7("");
|
|
1406
|
+
const [password, setPassword] = useState7("");
|
|
1407
|
+
const [error, setError] = useState7(null);
|
|
1408
|
+
const pathToRedirect = redirectAfterSuccess ?? returnPath;
|
|
1409
|
+
const handleSubmit = async (e) => {
|
|
1410
|
+
e.preventDefault();
|
|
1411
|
+
setError(null);
|
|
1412
|
+
try {
|
|
1413
|
+
await register(username.trim(), email.trim(), password);
|
|
1414
|
+
onSuccess?.();
|
|
1415
|
+
if (pathToRedirect) {
|
|
1416
|
+
if (onRedirect) {
|
|
1417
|
+
onRedirect(pathToRedirect);
|
|
1418
|
+
} else if (typeof window !== "undefined") {
|
|
1419
|
+
window.location.href = pathToRedirect;
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
} catch (err) {
|
|
1423
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1424
|
+
setError(message);
|
|
1425
|
+
onError?.(err instanceof Error ? err : new Error(message));
|
|
1426
|
+
}
|
|
1427
|
+
};
|
|
1428
|
+
return /* @__PURE__ */ jsxs2(Card, { className: cn(className, classNames?.root), style, "data-cilantro-register-form": true, children: [
|
|
1429
|
+
/* @__PURE__ */ jsxs2(CardHeader, { className: classNames?.header, children: [
|
|
1430
|
+
/* @__PURE__ */ jsx8(CardTitle, { className: classNames?.title, children: title }),
|
|
1431
|
+
description != null && /* @__PURE__ */ jsx8(CardDescription, { className: classNames?.description, children: description })
|
|
1432
|
+
] }),
|
|
1433
|
+
/* @__PURE__ */ jsx8(CardContent, { children: /* @__PURE__ */ jsxs2("form", { onSubmit: handleSubmit, className: cn("space-y-4", classNames?.form), children: [
|
|
1434
|
+
/* @__PURE__ */ jsxs2("div", { className: "space-y-2", children: [
|
|
1435
|
+
/* @__PURE__ */ jsx8(Label, { htmlFor: "cilantro-register-username", className: classNames?.label, children: "Username" }),
|
|
1436
|
+
/* @__PURE__ */ jsx8(
|
|
1437
|
+
Input,
|
|
1438
|
+
{
|
|
1439
|
+
id: "cilantro-register-username",
|
|
1440
|
+
type: "text",
|
|
1441
|
+
autoComplete: "username",
|
|
1442
|
+
className: classNames?.input,
|
|
1443
|
+
value: username,
|
|
1444
|
+
onChange: (e) => setUsername(e.target.value),
|
|
1445
|
+
placeholder: "Username",
|
|
1446
|
+
required: true,
|
|
1447
|
+
disabled: isLoading
|
|
1448
|
+
}
|
|
1449
|
+
)
|
|
1450
|
+
] }),
|
|
1451
|
+
/* @__PURE__ */ jsxs2("div", { className: "space-y-2", children: [
|
|
1452
|
+
/* @__PURE__ */ jsx8(Label, { htmlFor: "cilantro-register-email", className: classNames?.label, children: "Email" }),
|
|
1453
|
+
/* @__PURE__ */ jsx8(
|
|
1454
|
+
Input,
|
|
1455
|
+
{
|
|
1456
|
+
id: "cilantro-register-email",
|
|
1457
|
+
type: "email",
|
|
1458
|
+
autoComplete: "email",
|
|
1459
|
+
className: classNames?.input,
|
|
1460
|
+
value: email,
|
|
1461
|
+
onChange: (e) => setEmail(e.target.value),
|
|
1462
|
+
placeholder: "Email",
|
|
1463
|
+
required: true,
|
|
1464
|
+
disabled: isLoading
|
|
1465
|
+
}
|
|
1466
|
+
)
|
|
1467
|
+
] }),
|
|
1468
|
+
/* @__PURE__ */ jsxs2("div", { className: "space-y-2", children: [
|
|
1469
|
+
/* @__PURE__ */ jsx8(Label, { htmlFor: "cilantro-register-password", className: classNames?.label, children: "Password" }),
|
|
1470
|
+
/* @__PURE__ */ jsx8(
|
|
1471
|
+
Input,
|
|
1472
|
+
{
|
|
1473
|
+
id: "cilantro-register-password",
|
|
1474
|
+
type: "password",
|
|
1475
|
+
autoComplete: "new-password",
|
|
1476
|
+
className: classNames?.input,
|
|
1477
|
+
value: password,
|
|
1478
|
+
onChange: (e) => setPassword(e.target.value),
|
|
1479
|
+
placeholder: "Password",
|
|
1480
|
+
required: true,
|
|
1481
|
+
disabled: isLoading
|
|
1482
|
+
}
|
|
1483
|
+
)
|
|
1484
|
+
] }),
|
|
1485
|
+
error && /* @__PURE__ */ jsx8(
|
|
1486
|
+
"div",
|
|
1487
|
+
{
|
|
1488
|
+
className: cn(
|
|
1489
|
+
"rounded-md border border-destructive/50 bg-destructive/10 px-3 py-2 text-sm text-destructive",
|
|
1490
|
+
classNames?.error
|
|
1491
|
+
),
|
|
1492
|
+
role: "alert",
|
|
1493
|
+
children: error
|
|
1494
|
+
}
|
|
1495
|
+
),
|
|
1496
|
+
/* @__PURE__ */ jsx8(
|
|
1497
|
+
Button,
|
|
1498
|
+
{
|
|
1499
|
+
type: "submit",
|
|
1500
|
+
size: "touch",
|
|
1501
|
+
className: cn("w-full", classNames?.submitButton),
|
|
1502
|
+
disabled: isLoading || !username.trim() || !email.trim() || !password,
|
|
1503
|
+
children: isLoading ? "Creating account..." : submitLabel
|
|
1504
|
+
}
|
|
1505
|
+
),
|
|
1506
|
+
renderSwitchToLogin && /* @__PURE__ */ jsx8("div", { className: "text-center text-sm text-muted-foreground", children: renderSwitchToLogin() })
|
|
1507
|
+
] }) })
|
|
1508
|
+
] });
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
// src/components/auth/LogoutButton.tsx
|
|
1512
|
+
import { useState as useState8 } from "react";
|
|
1293
1513
|
|
|
1294
1514
|
// src/ui/dialog.tsx
|
|
1295
1515
|
import * as React5 from "react";
|
|
1296
1516
|
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
1297
|
-
import { jsx as
|
|
1517
|
+
import { jsx as jsx9, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1298
1518
|
var Dialog = DialogPrimitive.Root;
|
|
1299
1519
|
var DialogPortal = DialogPrimitive.Portal;
|
|
1300
|
-
var DialogOverlay = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
1520
|
+
var DialogOverlay = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx9(
|
|
1301
1521
|
DialogPrimitive.Overlay,
|
|
1302
1522
|
{
|
|
1303
1523
|
ref,
|
|
@@ -1309,9 +1529,9 @@ var DialogOverlay = React5.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
1309
1529
|
}
|
|
1310
1530
|
));
|
|
1311
1531
|
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
1312
|
-
var DialogContent = React5.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */
|
|
1313
|
-
/* @__PURE__ */
|
|
1314
|
-
/* @__PURE__ */
|
|
1532
|
+
var DialogContent = React5.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs3(DialogPortal, { children: [
|
|
1533
|
+
/* @__PURE__ */ jsx9(DialogOverlay, {}),
|
|
1534
|
+
/* @__PURE__ */ jsx9(
|
|
1315
1535
|
DialogPrimitive.Content,
|
|
1316
1536
|
{
|
|
1317
1537
|
ref,
|
|
@@ -1325,9 +1545,9 @@ var DialogContent = React5.forwardRef(({ className, children, ...props }, ref) =
|
|
|
1325
1545
|
)
|
|
1326
1546
|
] }));
|
|
1327
1547
|
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
1328
|
-
var DialogHeader = ({ className, ...props }) => /* @__PURE__ */
|
|
1548
|
+
var DialogHeader = ({ className, ...props }) => /* @__PURE__ */ jsx9("div", { className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className), ...props });
|
|
1329
1549
|
DialogHeader.displayName = "DialogHeader";
|
|
1330
|
-
var DialogFooter = ({ className, ...props }) => /* @__PURE__ */
|
|
1550
|
+
var DialogFooter = ({ className, ...props }) => /* @__PURE__ */ jsx9(
|
|
1331
1551
|
"div",
|
|
1332
1552
|
{
|
|
1333
1553
|
className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className),
|
|
@@ -1335,7 +1555,7 @@ var DialogFooter = ({ className, ...props }) => /* @__PURE__ */ jsx8(
|
|
|
1335
1555
|
}
|
|
1336
1556
|
);
|
|
1337
1557
|
DialogFooter.displayName = "DialogFooter";
|
|
1338
|
-
var DialogTitle = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
1558
|
+
var DialogTitle = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx9(
|
|
1339
1559
|
DialogPrimitive.Title,
|
|
1340
1560
|
{
|
|
1341
1561
|
ref,
|
|
@@ -1344,7 +1564,7 @@ var DialogTitle = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
1344
1564
|
}
|
|
1345
1565
|
));
|
|
1346
1566
|
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
1347
|
-
var DialogDescription = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
1567
|
+
var DialogDescription = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx9(
|
|
1348
1568
|
DialogPrimitive.Description,
|
|
1349
1569
|
{
|
|
1350
1570
|
ref,
|
|
@@ -1355,19 +1575,28 @@ var DialogDescription = React5.forwardRef(({ className, ...props }, ref) => /* @
|
|
|
1355
1575
|
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
1356
1576
|
|
|
1357
1577
|
// src/components/auth/LogoutButton.tsx
|
|
1358
|
-
import { Fragment, jsx as
|
|
1578
|
+
import { Fragment, jsx as jsx10, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1359
1579
|
function LogoutButton({
|
|
1360
1580
|
onLogout,
|
|
1581
|
+
redirectAfterLogout,
|
|
1582
|
+
onRedirect,
|
|
1361
1583
|
confirmBeforeLogout = false,
|
|
1362
1584
|
className,
|
|
1363
1585
|
children
|
|
1364
1586
|
}) {
|
|
1365
1587
|
const { logout } = useAuth();
|
|
1366
|
-
const [confirmOpen, setConfirmOpen] =
|
|
1588
|
+
const [confirmOpen, setConfirmOpen] = useState8(false);
|
|
1367
1589
|
const handleLogout = () => {
|
|
1368
1590
|
logout();
|
|
1369
1591
|
setConfirmOpen(false);
|
|
1370
1592
|
onLogout?.();
|
|
1593
|
+
if (redirectAfterLogout) {
|
|
1594
|
+
if (onRedirect) {
|
|
1595
|
+
onRedirect(redirectAfterLogout);
|
|
1596
|
+
} else if (typeof window !== "undefined") {
|
|
1597
|
+
window.location.href = redirectAfterLogout;
|
|
1598
|
+
}
|
|
1599
|
+
}
|
|
1371
1600
|
};
|
|
1372
1601
|
const handleClick = () => {
|
|
1373
1602
|
if (confirmBeforeLogout) {
|
|
@@ -1376,8 +1605,8 @@ function LogoutButton({
|
|
|
1376
1605
|
handleLogout();
|
|
1377
1606
|
}
|
|
1378
1607
|
};
|
|
1379
|
-
return /* @__PURE__ */
|
|
1380
|
-
/* @__PURE__ */
|
|
1608
|
+
return /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
1609
|
+
/* @__PURE__ */ jsx10(
|
|
1381
1610
|
Button,
|
|
1382
1611
|
{
|
|
1383
1612
|
type: "button",
|
|
@@ -1388,24 +1617,27 @@ function LogoutButton({
|
|
|
1388
1617
|
children: children ?? "Log out"
|
|
1389
1618
|
}
|
|
1390
1619
|
),
|
|
1391
|
-
confirmBeforeLogout && /* @__PURE__ */
|
|
1392
|
-
/* @__PURE__ */
|
|
1393
|
-
/* @__PURE__ */
|
|
1394
|
-
/* @__PURE__ */
|
|
1620
|
+
confirmBeforeLogout && /* @__PURE__ */ jsx10(Dialog, { open: confirmOpen, onOpenChange: setConfirmOpen, children: /* @__PURE__ */ jsxs4(DialogContent, { children: [
|
|
1621
|
+
/* @__PURE__ */ jsxs4(DialogHeader, { children: [
|
|
1622
|
+
/* @__PURE__ */ jsx10(DialogTitle, { children: "Log out?" }),
|
|
1623
|
+
/* @__PURE__ */ jsx10(DialogDescription, { children: "Are you sure you want to log out?" })
|
|
1395
1624
|
] }),
|
|
1396
|
-
/* @__PURE__ */
|
|
1397
|
-
/* @__PURE__ */
|
|
1398
|
-
/* @__PURE__ */
|
|
1625
|
+
/* @__PURE__ */ jsxs4(DialogFooter, { children: [
|
|
1626
|
+
/* @__PURE__ */ jsx10(Button, { variant: "outline", onClick: () => setConfirmOpen(false), children: "Cancel" }),
|
|
1627
|
+
/* @__PURE__ */ jsx10(Button, { variant: "destructive", onClick: handleLogout, children: "Log out" })
|
|
1399
1628
|
] })
|
|
1400
1629
|
] }) })
|
|
1401
1630
|
] });
|
|
1402
1631
|
}
|
|
1403
1632
|
|
|
1633
|
+
// src/components/auth/AuthGuard.tsx
|
|
1634
|
+
import { useMemo as useMemo4 } from "react";
|
|
1635
|
+
|
|
1404
1636
|
// src/ui/skeleton.tsx
|
|
1405
1637
|
import * as React6 from "react";
|
|
1406
|
-
import { jsx as
|
|
1638
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
1407
1639
|
var Skeleton = React6.forwardRef(
|
|
1408
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
1640
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx11(
|
|
1409
1641
|
"div",
|
|
1410
1642
|
{
|
|
1411
1643
|
ref,
|
|
@@ -1417,47 +1649,166 @@ var Skeleton = React6.forwardRef(
|
|
|
1417
1649
|
Skeleton.displayName = "Skeleton";
|
|
1418
1650
|
|
|
1419
1651
|
// src/components/auth/AuthGuard.tsx
|
|
1420
|
-
import { Fragment as Fragment2, jsx as
|
|
1652
|
+
import { Fragment as Fragment2, jsx as jsx12, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1653
|
+
var LAYOUT_CLASSES = {
|
|
1654
|
+
inline: "",
|
|
1655
|
+
centered: "flex min-h-[280px] items-center justify-center p-6",
|
|
1656
|
+
fullscreen: "fixed inset-0 z-50 flex min-h-screen items-center justify-center bg-background p-4"
|
|
1657
|
+
};
|
|
1658
|
+
function getCurrentReturnPath(returnUrlParam) {
|
|
1659
|
+
if (typeof window === "undefined") return "/";
|
|
1660
|
+
const params = new URLSearchParams(window.location.search);
|
|
1661
|
+
const existing = params.get(returnUrlParam);
|
|
1662
|
+
if (existing && existing.startsWith("/")) return existing;
|
|
1663
|
+
const path = window.location.pathname + window.location.search;
|
|
1664
|
+
return path || "/";
|
|
1665
|
+
}
|
|
1421
1666
|
function AuthGuard({
|
|
1422
1667
|
children,
|
|
1423
1668
|
fallback,
|
|
1424
1669
|
redirectTo,
|
|
1670
|
+
onRedirect,
|
|
1671
|
+
returnUrlParam = "returnUrl",
|
|
1672
|
+
layout = "inline",
|
|
1425
1673
|
className,
|
|
1426
1674
|
classNames,
|
|
1427
1675
|
showFallback = true,
|
|
1428
1676
|
useSkeleton = false
|
|
1429
1677
|
}) {
|
|
1430
1678
|
const { isAuthenticated, isLoading } = useCilantroAuth();
|
|
1679
|
+
const redirectPath = useMemo4(() => {
|
|
1680
|
+
if (!redirectTo) return null;
|
|
1681
|
+
const returnPath = getCurrentReturnPath(returnUrlParam);
|
|
1682
|
+
const sep = redirectTo.includes("?") ? "&" : "?";
|
|
1683
|
+
return `${redirectTo}${sep}${returnUrlParam}=${encodeURIComponent(returnPath)}`;
|
|
1684
|
+
}, [redirectTo, returnUrlParam]);
|
|
1431
1685
|
if (isLoading) {
|
|
1432
|
-
|
|
1686
|
+
const loadingContent = useSkeleton ? /* @__PURE__ */ jsxs5("div", { className: cn("rounded-lg border border-input p-6 space-y-4 w-full max-w-sm", classNames?.fallback), children: [
|
|
1687
|
+
/* @__PURE__ */ jsx12(Skeleton, { className: cn("h-7 w-2/3 rounded", classNames?.skeleton) }),
|
|
1688
|
+
/* @__PURE__ */ jsx12(Skeleton, { className: cn("h-4 w-full rounded", classNames?.skeleton) }),
|
|
1689
|
+
/* @__PURE__ */ jsx12(Skeleton, { className: cn("h-10 w-full rounded", classNames?.skeleton) }),
|
|
1690
|
+
/* @__PURE__ */ jsx12(Skeleton, { className: cn("h-10 w-full rounded", classNames?.skeleton) })
|
|
1691
|
+
] }) : /* @__PURE__ */ jsxs5("div", { className: "flex flex-col items-center gap-3", children: [
|
|
1692
|
+
/* @__PURE__ */ jsx12(
|
|
1693
|
+
"div",
|
|
1694
|
+
{
|
|
1695
|
+
className: "h-8 w-8 animate-spin rounded-full border-2 border-primary border-t-transparent",
|
|
1696
|
+
"aria-hidden": true
|
|
1697
|
+
}
|
|
1698
|
+
),
|
|
1699
|
+
/* @__PURE__ */ jsx12("p", { className: "text-sm text-muted-foreground", children: "Loading..." })
|
|
1700
|
+
] });
|
|
1701
|
+
return /* @__PURE__ */ jsx12(
|
|
1433
1702
|
"div",
|
|
1434
1703
|
{
|
|
1435
|
-
className: cn(
|
|
1704
|
+
className: cn(
|
|
1705
|
+
LAYOUT_CLASSES[layout],
|
|
1706
|
+
className,
|
|
1707
|
+
classNames?.root,
|
|
1708
|
+
classNames?.loading
|
|
1709
|
+
),
|
|
1436
1710
|
"data-cilantro-auth-guard": true,
|
|
1437
1711
|
"aria-busy": "true",
|
|
1438
1712
|
"aria-live": "polite",
|
|
1439
|
-
children:
|
|
1440
|
-
/* @__PURE__ */ jsx11(Skeleton, { className: cn("h-6 w-2/3 rounded", classNames?.skeleton) }),
|
|
1441
|
-
/* @__PURE__ */ jsx11(Skeleton, { className: cn("h-4 w-full rounded", classNames?.skeleton) }),
|
|
1442
|
-
/* @__PURE__ */ jsx11(Skeleton, { className: cn("h-4 w-[80%] rounded", classNames?.skeleton) })
|
|
1443
|
-
] }) : /* @__PURE__ */ jsx11("div", { className: cn("text-sm text-muted-foreground", classNames?.fallback), children: "Loading..." })
|
|
1713
|
+
children: /* @__PURE__ */ jsx12("div", { className: cn(layout !== "inline" && "w-full max-w-sm", classNames?.layout), children: loadingContent })
|
|
1444
1714
|
}
|
|
1445
1715
|
);
|
|
1446
1716
|
}
|
|
1447
1717
|
if (!isAuthenticated) {
|
|
1718
|
+
if (!showFallback && redirectPath) {
|
|
1719
|
+
if (onRedirect) {
|
|
1720
|
+
onRedirect(redirectPath);
|
|
1721
|
+
} else if (typeof window !== "undefined") {
|
|
1722
|
+
window.location.href = redirectPath;
|
|
1723
|
+
}
|
|
1724
|
+
return null;
|
|
1725
|
+
}
|
|
1448
1726
|
if (!showFallback) return null;
|
|
1449
|
-
if (
|
|
1450
|
-
|
|
1727
|
+
if (redirectPath) {
|
|
1728
|
+
if (onRedirect) {
|
|
1729
|
+
onRedirect(redirectPath);
|
|
1730
|
+
} else if (typeof window !== "undefined") {
|
|
1731
|
+
window.location.href = redirectPath;
|
|
1732
|
+
}
|
|
1451
1733
|
return null;
|
|
1452
1734
|
}
|
|
1453
|
-
|
|
1735
|
+
const returnPath = getCurrentReturnPath(returnUrlParam);
|
|
1736
|
+
const fallbackContent = fallback ?? /* @__PURE__ */ jsx12(
|
|
1737
|
+
LoginForm,
|
|
1738
|
+
{
|
|
1739
|
+
className: classNames?.fallback,
|
|
1740
|
+
redirectAfterSuccess: returnPath,
|
|
1741
|
+
returnUrlParam,
|
|
1742
|
+
onRedirect
|
|
1743
|
+
}
|
|
1744
|
+
);
|
|
1745
|
+
return /* @__PURE__ */ jsx12(
|
|
1746
|
+
"div",
|
|
1747
|
+
{
|
|
1748
|
+
className: cn(
|
|
1749
|
+
LAYOUT_CLASSES[layout],
|
|
1750
|
+
className,
|
|
1751
|
+
classNames?.root
|
|
1752
|
+
),
|
|
1753
|
+
"data-cilantro-auth-guard": true,
|
|
1754
|
+
children: /* @__PURE__ */ jsx12("div", { className: cn(layout !== "inline" && "w-full max-w-sm", classNames?.layout), children: fallbackContent })
|
|
1755
|
+
}
|
|
1756
|
+
);
|
|
1454
1757
|
}
|
|
1455
|
-
return /* @__PURE__ */
|
|
1758
|
+
return /* @__PURE__ */ jsx12(Fragment2, { children });
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1761
|
+
// src/components/auth/AuthShell.tsx
|
|
1762
|
+
import { jsx as jsx13, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1763
|
+
var MAX_WIDTH_CLASSES = {
|
|
1764
|
+
sm: "max-w-sm",
|
|
1765
|
+
md: "max-w-md",
|
|
1766
|
+
lg: "max-w-lg"
|
|
1767
|
+
};
|
|
1768
|
+
function AuthShell({
|
|
1769
|
+
children,
|
|
1770
|
+
logo,
|
|
1771
|
+
maxWidth = "sm",
|
|
1772
|
+
className,
|
|
1773
|
+
classNames
|
|
1774
|
+
}) {
|
|
1775
|
+
return /* @__PURE__ */ jsx13(
|
|
1776
|
+
"div",
|
|
1777
|
+
{
|
|
1778
|
+
className: cn(
|
|
1779
|
+
"flex min-h-screen flex-col items-center justify-center bg-background p-4 sm:p-6",
|
|
1780
|
+
className,
|
|
1781
|
+
classNames?.root
|
|
1782
|
+
),
|
|
1783
|
+
"data-cilantro-auth-shell": true,
|
|
1784
|
+
children: /* @__PURE__ */ jsxs6(
|
|
1785
|
+
"div",
|
|
1786
|
+
{
|
|
1787
|
+
className: cn(
|
|
1788
|
+
"w-full space-y-6",
|
|
1789
|
+
MAX_WIDTH_CLASSES[maxWidth],
|
|
1790
|
+
classNames?.inner
|
|
1791
|
+
),
|
|
1792
|
+
children: [
|
|
1793
|
+
logo && /* @__PURE__ */ jsx13(
|
|
1794
|
+
"div",
|
|
1795
|
+
{
|
|
1796
|
+
className: cn("flex justify-center", classNames?.logo),
|
|
1797
|
+
"data-cilantro-auth-shell-logo": true,
|
|
1798
|
+
children: logo
|
|
1799
|
+
}
|
|
1800
|
+
),
|
|
1801
|
+
children
|
|
1802
|
+
]
|
|
1803
|
+
}
|
|
1804
|
+
)
|
|
1805
|
+
}
|
|
1806
|
+
);
|
|
1456
1807
|
}
|
|
1457
1808
|
|
|
1458
1809
|
// src/components/signers/CreateEmailSignerForm.tsx
|
|
1459
|
-
import { useState as
|
|
1460
|
-
import { jsx as
|
|
1810
|
+
import { useState as useState9 } from "react";
|
|
1811
|
+
import { jsx as jsx14, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1461
1812
|
function CreateEmailSignerForm({
|
|
1462
1813
|
walletId,
|
|
1463
1814
|
onCreated,
|
|
@@ -1465,8 +1816,8 @@ function CreateEmailSignerForm({
|
|
|
1465
1816
|
className
|
|
1466
1817
|
}) {
|
|
1467
1818
|
const { createEmailSigner, isLoading } = useSigners(walletId);
|
|
1468
|
-
const [email, setEmail] =
|
|
1469
|
-
const [error, setError] =
|
|
1819
|
+
const [email, setEmail] = useState9("");
|
|
1820
|
+
const [error, setError] = useState9(null);
|
|
1470
1821
|
const handleSubmit = async (e) => {
|
|
1471
1822
|
e.preventDefault();
|
|
1472
1823
|
setError(null);
|
|
@@ -1480,10 +1831,10 @@ function CreateEmailSignerForm({
|
|
|
1480
1831
|
onError?.(err instanceof Error ? err : new Error(message));
|
|
1481
1832
|
}
|
|
1482
1833
|
};
|
|
1483
|
-
return /* @__PURE__ */
|
|
1484
|
-
/* @__PURE__ */
|
|
1485
|
-
/* @__PURE__ */
|
|
1486
|
-
/* @__PURE__ */
|
|
1834
|
+
return /* @__PURE__ */ jsxs7("form", { onSubmit: handleSubmit, className: cn("space-y-4", className), "data-cilantro-create-email-signer": true, children: [
|
|
1835
|
+
/* @__PURE__ */ jsxs7("div", { className: "space-y-2", children: [
|
|
1836
|
+
/* @__PURE__ */ jsx14(Label, { htmlFor: "cilantro-email-signer-email", children: "Email" }),
|
|
1837
|
+
/* @__PURE__ */ jsx14(
|
|
1487
1838
|
Input,
|
|
1488
1839
|
{
|
|
1489
1840
|
id: "cilantro-email-signer-email",
|
|
@@ -1497,14 +1848,14 @@ function CreateEmailSignerForm({
|
|
|
1497
1848
|
}
|
|
1498
1849
|
)
|
|
1499
1850
|
] }),
|
|
1500
|
-
error && /* @__PURE__ */
|
|
1501
|
-
/* @__PURE__ */
|
|
1851
|
+
error && /* @__PURE__ */ jsx14("div", { className: "rounded-md border border-destructive/50 bg-destructive/10 px-3 py-2 text-sm text-destructive", role: "alert", children: error }),
|
|
1852
|
+
/* @__PURE__ */ jsx14(Button, { type: "submit", disabled: isLoading || !email.trim(), children: isLoading ? "Creating..." : "Create email signer" })
|
|
1502
1853
|
] });
|
|
1503
1854
|
}
|
|
1504
1855
|
|
|
1505
1856
|
// src/components/signers/CreatePhoneSignerForm.tsx
|
|
1506
|
-
import { useState as
|
|
1507
|
-
import { jsx as
|
|
1857
|
+
import { useState as useState10 } from "react";
|
|
1858
|
+
import { jsx as jsx15, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1508
1859
|
function CreatePhoneSignerForm({
|
|
1509
1860
|
walletId,
|
|
1510
1861
|
onCreated,
|
|
@@ -1512,8 +1863,8 @@ function CreatePhoneSignerForm({
|
|
|
1512
1863
|
className
|
|
1513
1864
|
}) {
|
|
1514
1865
|
const { createPhoneSigner, isLoading } = useSigners(walletId);
|
|
1515
|
-
const [phone, setPhone] =
|
|
1516
|
-
const [error, setError] =
|
|
1866
|
+
const [phone, setPhone] = useState10("");
|
|
1867
|
+
const [error, setError] = useState10(null);
|
|
1517
1868
|
const handleSubmit = async (e) => {
|
|
1518
1869
|
e.preventDefault();
|
|
1519
1870
|
setError(null);
|
|
@@ -1527,10 +1878,10 @@ function CreatePhoneSignerForm({
|
|
|
1527
1878
|
onError?.(err instanceof Error ? err : new Error(message));
|
|
1528
1879
|
}
|
|
1529
1880
|
};
|
|
1530
|
-
return /* @__PURE__ */
|
|
1531
|
-
/* @__PURE__ */
|
|
1532
|
-
/* @__PURE__ */
|
|
1533
|
-
/* @__PURE__ */
|
|
1881
|
+
return /* @__PURE__ */ jsxs8("form", { onSubmit: handleSubmit, className: cn("space-y-4", className), "data-cilantro-create-phone-signer": true, children: [
|
|
1882
|
+
/* @__PURE__ */ jsxs8("div", { className: "space-y-2", children: [
|
|
1883
|
+
/* @__PURE__ */ jsx15(Label, { htmlFor: "cilantro-phone-signer-phone", children: "Phone number" }),
|
|
1884
|
+
/* @__PURE__ */ jsx15(
|
|
1534
1885
|
Input,
|
|
1535
1886
|
{
|
|
1536
1887
|
id: "cilantro-phone-signer-phone",
|
|
@@ -1544,14 +1895,14 @@ function CreatePhoneSignerForm({
|
|
|
1544
1895
|
}
|
|
1545
1896
|
)
|
|
1546
1897
|
] }),
|
|
1547
|
-
error && /* @__PURE__ */
|
|
1548
|
-
/* @__PURE__ */
|
|
1898
|
+
error && /* @__PURE__ */ jsx15("div", { className: "rounded-md border border-destructive/50 bg-destructive/10 px-3 py-2 text-sm text-destructive", role: "alert", children: error }),
|
|
1899
|
+
/* @__PURE__ */ jsx15(Button, { type: "submit", disabled: isLoading || !phone.trim(), children: isLoading ? "Creating..." : "Create phone signer" })
|
|
1549
1900
|
] });
|
|
1550
1901
|
}
|
|
1551
1902
|
|
|
1552
1903
|
// src/components/signers/AddPasskeyButton.tsx
|
|
1553
|
-
import { useState as
|
|
1554
|
-
import { jsx as
|
|
1904
|
+
import { useState as useState11 } from "react";
|
|
1905
|
+
import { jsx as jsx16, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1555
1906
|
function AddPasskeyButton({
|
|
1556
1907
|
walletId,
|
|
1557
1908
|
onRegistered,
|
|
@@ -1560,7 +1911,7 @@ function AddPasskeyButton({
|
|
|
1560
1911
|
children
|
|
1561
1912
|
}) {
|
|
1562
1913
|
const { isSupported, register, isLoading } = usePasskey(walletId);
|
|
1563
|
-
const [error, setError] =
|
|
1914
|
+
const [error, setError] = useState11(null);
|
|
1564
1915
|
const handleClick = async () => {
|
|
1565
1916
|
setError(null);
|
|
1566
1917
|
try {
|
|
@@ -1573,15 +1924,15 @@ function AddPasskeyButton({
|
|
|
1573
1924
|
}
|
|
1574
1925
|
};
|
|
1575
1926
|
if (!isSupported) return null;
|
|
1576
|
-
return /* @__PURE__ */
|
|
1577
|
-
/* @__PURE__ */
|
|
1578
|
-
error && /* @__PURE__ */
|
|
1927
|
+
return /* @__PURE__ */ jsxs9("div", { className: cn(className), "data-cilantro-add-passkey": true, children: [
|
|
1928
|
+
/* @__PURE__ */ jsx16(Button, { type: "button", variant: "outline", onClick: handleClick, disabled: isLoading, children: children ?? "Add Passkey" }),
|
|
1929
|
+
error && /* @__PURE__ */ jsx16("p", { className: "mt-2 text-sm text-destructive", role: "alert", children: error })
|
|
1579
1930
|
] });
|
|
1580
1931
|
}
|
|
1581
1932
|
|
|
1582
1933
|
// src/components/signers/SignerList.tsx
|
|
1583
|
-
import { useState as
|
|
1584
|
-
import { Fragment as Fragment3, jsx as
|
|
1934
|
+
import { useState as useState12 } from "react";
|
|
1935
|
+
import { Fragment as Fragment3, jsx as jsx17, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1585
1936
|
function SignerList({
|
|
1586
1937
|
walletId,
|
|
1587
1938
|
onRevoke,
|
|
@@ -1592,7 +1943,7 @@ function SignerList({
|
|
|
1592
1943
|
children
|
|
1593
1944
|
}) {
|
|
1594
1945
|
const { signers, isLoading, error, refresh, revokeSigner } = useSigners(walletId);
|
|
1595
|
-
const [addSignerOpen, setAddSignerOpen] =
|
|
1946
|
+
const [addSignerOpen, setAddSignerOpen] = useState12(false);
|
|
1596
1947
|
const handleAddSuccess = () => {
|
|
1597
1948
|
refresh();
|
|
1598
1949
|
setAddSignerOpen(false);
|
|
@@ -1606,7 +1957,7 @@ function SignerList({
|
|
|
1606
1957
|
}
|
|
1607
1958
|
};
|
|
1608
1959
|
if (children) {
|
|
1609
|
-
return /* @__PURE__ */
|
|
1960
|
+
return /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
1610
1961
|
children({
|
|
1611
1962
|
signers,
|
|
1612
1963
|
isLoading,
|
|
@@ -1614,24 +1965,24 @@ function SignerList({
|
|
|
1614
1965
|
refresh,
|
|
1615
1966
|
openAddSigner: () => setAddSignerOpen(true)
|
|
1616
1967
|
}),
|
|
1617
|
-
/* @__PURE__ */
|
|
1618
|
-
/* @__PURE__ */
|
|
1619
|
-
/* @__PURE__ */
|
|
1620
|
-
/* @__PURE__ */
|
|
1968
|
+
/* @__PURE__ */ jsx17(Dialog, { open: addSignerOpen, onOpenChange: setAddSignerOpen, children: /* @__PURE__ */ jsxs10(DialogContent, { children: [
|
|
1969
|
+
/* @__PURE__ */ jsx17(DialogHeader, { children: /* @__PURE__ */ jsx17(DialogTitle, { children: "Add signer" }) }),
|
|
1970
|
+
/* @__PURE__ */ jsxs10("div", { className: "space-y-4", children: [
|
|
1971
|
+
/* @__PURE__ */ jsx17(
|
|
1621
1972
|
CreateEmailSignerForm,
|
|
1622
1973
|
{
|
|
1623
1974
|
walletId,
|
|
1624
1975
|
onCreated: handleAddSuccess
|
|
1625
1976
|
}
|
|
1626
1977
|
),
|
|
1627
|
-
/* @__PURE__ */
|
|
1978
|
+
/* @__PURE__ */ jsx17(
|
|
1628
1979
|
CreatePhoneSignerForm,
|
|
1629
1980
|
{
|
|
1630
1981
|
walletId,
|
|
1631
1982
|
onCreated: handleAddSuccess
|
|
1632
1983
|
}
|
|
1633
1984
|
),
|
|
1634
|
-
/* @__PURE__ */
|
|
1985
|
+
/* @__PURE__ */ jsx17(
|
|
1635
1986
|
AddPasskeyButton,
|
|
1636
1987
|
{
|
|
1637
1988
|
walletId,
|
|
@@ -1643,12 +1994,12 @@ function SignerList({
|
|
|
1643
1994
|
] });
|
|
1644
1995
|
}
|
|
1645
1996
|
if (!walletId) {
|
|
1646
|
-
return /* @__PURE__ */
|
|
1997
|
+
return /* @__PURE__ */ jsx17("div", { className: cn(className, classNames?.root), "data-cilantro-signer-list": true, children: /* @__PURE__ */ jsx17("p", { className: cn("text-sm text-muted-foreground", classNames?.message), children: "Select a wallet first." }) });
|
|
1647
1998
|
}
|
|
1648
|
-
return /* @__PURE__ */
|
|
1649
|
-
/* @__PURE__ */
|
|
1650
|
-
/* @__PURE__ */
|
|
1651
|
-
/* @__PURE__ */
|
|
1999
|
+
return /* @__PURE__ */ jsxs10("div", { className: cn(className, classNames?.root), "data-cilantro-signer-list": true, "aria-busy": isLoading, "aria-live": "polite", children: [
|
|
2000
|
+
/* @__PURE__ */ jsxs10("div", { className: cn("flex items-center justify-between gap-2 mb-2", classNames?.header), children: [
|
|
2001
|
+
/* @__PURE__ */ jsx17("span", { className: "text-sm font-medium", children: "Signers" }),
|
|
2002
|
+
/* @__PURE__ */ jsx17(
|
|
1652
2003
|
Button,
|
|
1653
2004
|
{
|
|
1654
2005
|
type: "button",
|
|
@@ -1662,13 +2013,13 @@ function SignerList({
|
|
|
1662
2013
|
}
|
|
1663
2014
|
)
|
|
1664
2015
|
] }),
|
|
1665
|
-
isLoading && useSkeleton ? /* @__PURE__ */
|
|
1666
|
-
/* @__PURE__ */
|
|
1667
|
-
/* @__PURE__ */
|
|
1668
|
-
] }) : signers.length === 0 ? /* @__PURE__ */
|
|
1669
|
-
/* @__PURE__ */
|
|
1670
|
-
/* @__PURE__ */
|
|
1671
|
-
/* @__PURE__ */
|
|
2016
|
+
isLoading && useSkeleton ? /* @__PURE__ */ jsx17("div", { className: cn("space-y-1", classNames?.loading), "aria-busy": "true", "aria-live": "polite", children: [1, 2, 3].map((i) => /* @__PURE__ */ jsx17(Skeleton, { className: cn("h-5 w-full rounded-md", classNames?.skeleton) }, i)) }) : isLoading ? /* @__PURE__ */ jsx17("p", { className: cn("text-sm text-muted-foreground", classNames?.message), children: "Loading signers..." }) : error ? /* @__PURE__ */ jsxs10("div", { className: cn("rounded-md border border-destructive/50 bg-destructive/10 px-3 py-2", classNames?.message), role: "alert", children: [
|
|
2017
|
+
/* @__PURE__ */ jsx17("p", { className: "text-sm text-destructive", children: error }),
|
|
2018
|
+
/* @__PURE__ */ jsx17(Button, { type: "button", variant: "outline", size: "sm", className: "mt-2", onClick: () => refresh(), children: "Retry" })
|
|
2019
|
+
] }) : signers.length === 0 ? /* @__PURE__ */ jsxs10("div", { className: cn("rounded-md border border-input bg-muted/30 px-4 py-3 text-sm text-muted-foreground", classNames?.message), children: [
|
|
2020
|
+
/* @__PURE__ */ jsx17("p", { className: "font-medium text-foreground", children: "No signers" }),
|
|
2021
|
+
/* @__PURE__ */ jsx17("p", { className: "mt-1", children: "Add a signer to authorize transactions for this wallet." }),
|
|
2022
|
+
/* @__PURE__ */ jsx17(
|
|
1672
2023
|
Button,
|
|
1673
2024
|
{
|
|
1674
2025
|
type: "button",
|
|
@@ -1680,14 +2031,14 @@ function SignerList({
|
|
|
1680
2031
|
children: "Add signer"
|
|
1681
2032
|
}
|
|
1682
2033
|
)
|
|
1683
|
-
] }) : /* @__PURE__ */
|
|
1684
|
-
/* @__PURE__ */
|
|
2034
|
+
] }) : /* @__PURE__ */ jsx17("ul", { className: cn("space-y-1", classNames?.list), role: "list", children: signers.map((signer) => /* @__PURE__ */ jsxs10("li", { className: cn("flex items-center justify-between gap-2 text-sm", classNames?.item), children: [
|
|
2035
|
+
/* @__PURE__ */ jsxs10("span", { children: [
|
|
1685
2036
|
getSignerDisplayName(signer),
|
|
1686
2037
|
" (",
|
|
1687
2038
|
getSignerTypeLabel(signer.type || signer.signerType || ""),
|
|
1688
2039
|
")"
|
|
1689
2040
|
] }),
|
|
1690
|
-
onRevoke && /* @__PURE__ */
|
|
2041
|
+
onRevoke && /* @__PURE__ */ jsx17(
|
|
1691
2042
|
Button,
|
|
1692
2043
|
{
|
|
1693
2044
|
type: "button",
|
|
@@ -1700,19 +2051,19 @@ function SignerList({
|
|
|
1700
2051
|
}
|
|
1701
2052
|
)
|
|
1702
2053
|
] }, signer.id)) }),
|
|
1703
|
-
/* @__PURE__ */
|
|
1704
|
-
/* @__PURE__ */
|
|
1705
|
-
/* @__PURE__ */
|
|
1706
|
-
/* @__PURE__ */
|
|
1707
|
-
/* @__PURE__ */
|
|
1708
|
-
/* @__PURE__ */
|
|
2054
|
+
/* @__PURE__ */ jsx17(Dialog, { open: addSignerOpen, onOpenChange: setAddSignerOpen, children: /* @__PURE__ */ jsxs10(DialogContent, { children: [
|
|
2055
|
+
/* @__PURE__ */ jsx17(DialogHeader, { children: /* @__PURE__ */ jsx17(DialogTitle, { children: "Add signer" }) }),
|
|
2056
|
+
/* @__PURE__ */ jsxs10("div", { className: "space-y-4", children: [
|
|
2057
|
+
/* @__PURE__ */ jsx17(CreateEmailSignerForm, { walletId, onCreated: handleAddSuccess }),
|
|
2058
|
+
/* @__PURE__ */ jsx17(CreatePhoneSignerForm, { walletId, onCreated: handleAddSuccess }),
|
|
2059
|
+
/* @__PURE__ */ jsx17(AddPasskeyButton, { walletId, onRegistered: handleAddSuccess })
|
|
1709
2060
|
] })
|
|
1710
2061
|
] }) })
|
|
1711
2062
|
] });
|
|
1712
2063
|
}
|
|
1713
2064
|
|
|
1714
2065
|
// src/components/signers/SignerSelector.tsx
|
|
1715
|
-
import { Fragment as Fragment4, jsx as
|
|
2066
|
+
import { Fragment as Fragment4, jsx as jsx18, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1716
2067
|
function SignerSelector({
|
|
1717
2068
|
walletId,
|
|
1718
2069
|
value,
|
|
@@ -1740,7 +2091,7 @@ function SignerSelector({
|
|
|
1740
2091
|
};
|
|
1741
2092
|
if (!walletId && !selectedWalletId) return null;
|
|
1742
2093
|
if (children) {
|
|
1743
|
-
return /* @__PURE__ */
|
|
2094
|
+
return /* @__PURE__ */ jsx18(Fragment4, { children: children({
|
|
1744
2095
|
signers: availableSigners,
|
|
1745
2096
|
selectedSigner,
|
|
1746
2097
|
onSignerSelect: handleSelect,
|
|
@@ -1748,7 +2099,7 @@ function SignerSelector({
|
|
|
1748
2099
|
}) });
|
|
1749
2100
|
}
|
|
1750
2101
|
if (renderList) {
|
|
1751
|
-
return /* @__PURE__ */
|
|
2102
|
+
return /* @__PURE__ */ jsx18("div", { className: cn(className, classNames?.root), "data-cilantro-signer-selector": true, children: renderList({
|
|
1752
2103
|
signers: availableSigners,
|
|
1753
2104
|
selectedSigner: selectedSigner ?? null,
|
|
1754
2105
|
onSelect: handleSelect,
|
|
@@ -1758,8 +2109,8 @@ function SignerSelector({
|
|
|
1758
2109
|
getSignerUniqueId
|
|
1759
2110
|
}) });
|
|
1760
2111
|
}
|
|
1761
|
-
const loadingContent = isLoadingSigners && useSkeleton ? /* @__PURE__ */
|
|
1762
|
-
return /* @__PURE__ */
|
|
2112
|
+
const loadingContent = isLoadingSigners && useSkeleton ? /* @__PURE__ */ jsx18("div", { className: cn("space-y-1", classNames?.loading), "aria-busy": "true", "aria-live": "polite", children: [1, 2, 3].map((i) => /* @__PURE__ */ jsx18(Skeleton, { className: cn("h-8 w-full rounded-md", classNames?.skeleton) }, i)) }) : isLoadingSigners ? /* @__PURE__ */ jsx18("p", { className: cn("text-sm text-muted-foreground", classNames?.message), children: "Loading signers..." }) : null;
|
|
2113
|
+
return /* @__PURE__ */ jsx18(
|
|
1763
2114
|
"div",
|
|
1764
2115
|
{
|
|
1765
2116
|
className: cn(className, classNames?.root),
|
|
@@ -1768,7 +2119,7 @@ function SignerSelector({
|
|
|
1768
2119
|
"aria-label": "Select signer",
|
|
1769
2120
|
"aria-busy": isLoadingSigners,
|
|
1770
2121
|
"aria-live": "polite",
|
|
1771
|
-
children: loadingContent ?? (availableSigners.length === 0 ? /* @__PURE__ */
|
|
2122
|
+
children: loadingContent ?? (availableSigners.length === 0 ? /* @__PURE__ */ jsx18("p", { className: cn("text-sm text-muted-foreground", classNames?.message), children: "No signers for this wallet." }) : /* @__PURE__ */ jsx18("ul", { className: cn("space-y-1", classNames?.list), children: availableSigners.map((signer) => /* @__PURE__ */ jsx18("li", { children: /* @__PURE__ */ jsxs11(
|
|
1772
2123
|
Button,
|
|
1773
2124
|
{
|
|
1774
2125
|
type: "button",
|
|
@@ -1790,8 +2141,8 @@ function SignerSelector({
|
|
|
1790
2141
|
}
|
|
1791
2142
|
|
|
1792
2143
|
// src/components/wallet/ConnectWalletButton.tsx
|
|
1793
|
-
import { useState as
|
|
1794
|
-
import { jsx as
|
|
2144
|
+
import { useState as useState13 } from "react";
|
|
2145
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
1795
2146
|
function ConnectWalletButton({
|
|
1796
2147
|
onConnect,
|
|
1797
2148
|
onDisconnect,
|
|
@@ -1799,7 +2150,7 @@ function ConnectWalletButton({
|
|
|
1799
2150
|
children
|
|
1800
2151
|
}) {
|
|
1801
2152
|
const { wallets, connectedWallet, connect, disconnect } = useExternalWallet();
|
|
1802
|
-
const [loading, setLoading] =
|
|
2153
|
+
const [loading, setLoading] = useState13(false);
|
|
1803
2154
|
const handleConnect = async (wallet) => {
|
|
1804
2155
|
setLoading(true);
|
|
1805
2156
|
try {
|
|
@@ -1819,7 +2170,7 @@ function ConnectWalletButton({
|
|
|
1819
2170
|
}
|
|
1820
2171
|
};
|
|
1821
2172
|
if (connectedWallet) {
|
|
1822
|
-
return /* @__PURE__ */
|
|
2173
|
+
return /* @__PURE__ */ jsx19(
|
|
1823
2174
|
Button,
|
|
1824
2175
|
{
|
|
1825
2176
|
type: "button",
|
|
@@ -1833,9 +2184,9 @@ function ConnectWalletButton({
|
|
|
1833
2184
|
);
|
|
1834
2185
|
}
|
|
1835
2186
|
if (wallets.length === 0) {
|
|
1836
|
-
return /* @__PURE__ */
|
|
2187
|
+
return /* @__PURE__ */ jsx19(Button, { type: "button", variant: "outline", className: cn(className), disabled: true, "data-cilantro-connect-wallet": true, children: "No wallet detected" });
|
|
1837
2188
|
}
|
|
1838
|
-
return /* @__PURE__ */
|
|
2189
|
+
return /* @__PURE__ */ jsx19(
|
|
1839
2190
|
Button,
|
|
1840
2191
|
{
|
|
1841
2192
|
type: "button",
|
|
@@ -1850,8 +2201,8 @@ function ConnectWalletButton({
|
|
|
1850
2201
|
}
|
|
1851
2202
|
|
|
1852
2203
|
// src/components/wallet/CreateWalletForm.tsx
|
|
1853
|
-
import { useState as
|
|
1854
|
-
import { jsx as
|
|
2204
|
+
import { useState as useState14 } from "react";
|
|
2205
|
+
import { jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1855
2206
|
function CreateWalletForm({
|
|
1856
2207
|
userId,
|
|
1857
2208
|
onCreated,
|
|
@@ -1859,8 +2210,8 @@ function CreateWalletForm({
|
|
|
1859
2210
|
className
|
|
1860
2211
|
}) {
|
|
1861
2212
|
const { createWallet, isLoading } = useWallet();
|
|
1862
|
-
const [name, setName] =
|
|
1863
|
-
const [error, setError] =
|
|
2213
|
+
const [name, setName] = useState14("");
|
|
2214
|
+
const [error, setError] = useState14(null);
|
|
1864
2215
|
const handleSubmit = async (e) => {
|
|
1865
2216
|
e.preventDefault();
|
|
1866
2217
|
setError(null);
|
|
@@ -1874,10 +2225,10 @@ function CreateWalletForm({
|
|
|
1874
2225
|
onError?.(err instanceof Error ? err : new Error(message));
|
|
1875
2226
|
}
|
|
1876
2227
|
};
|
|
1877
|
-
return /* @__PURE__ */
|
|
1878
|
-
/* @__PURE__ */
|
|
1879
|
-
/* @__PURE__ */
|
|
1880
|
-
/* @__PURE__ */
|
|
2228
|
+
return /* @__PURE__ */ jsxs12("form", { onSubmit: handleSubmit, className: cn("space-y-4", className), "data-cilantro-create-wallet": true, children: [
|
|
2229
|
+
/* @__PURE__ */ jsxs12("div", { className: "space-y-2", children: [
|
|
2230
|
+
/* @__PURE__ */ jsx20(Label, { htmlFor: "cilantro-wallet-name", children: "Wallet name" }),
|
|
2231
|
+
/* @__PURE__ */ jsx20(
|
|
1881
2232
|
Input,
|
|
1882
2233
|
{
|
|
1883
2234
|
id: "cilantro-wallet-name",
|
|
@@ -1890,18 +2241,18 @@ function CreateWalletForm({
|
|
|
1890
2241
|
}
|
|
1891
2242
|
)
|
|
1892
2243
|
] }),
|
|
1893
|
-
error && /* @__PURE__ */
|
|
1894
|
-
/* @__PURE__ */
|
|
2244
|
+
error && /* @__PURE__ */ jsx20("div", { className: "rounded-md border border-destructive/50 bg-destructive/10 px-3 py-2 text-sm text-destructive", role: "alert", children: error }),
|
|
2245
|
+
/* @__PURE__ */ jsx20(Button, { type: "submit", disabled: isLoading || !name.trim(), children: isLoading ? "Creating..." : "Create wallet" })
|
|
1895
2246
|
] });
|
|
1896
2247
|
}
|
|
1897
2248
|
|
|
1898
2249
|
// src/ui/select.tsx
|
|
1899
2250
|
import * as React7 from "react";
|
|
1900
2251
|
import * as SelectPrimitive from "@radix-ui/react-select";
|
|
1901
|
-
import { jsx as
|
|
2252
|
+
import { jsx as jsx21, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1902
2253
|
var Select = SelectPrimitive.Root;
|
|
1903
2254
|
var SelectValue = SelectPrimitive.Value;
|
|
1904
|
-
var SelectTrigger = React7.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */
|
|
2255
|
+
var SelectTrigger = React7.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs13(
|
|
1905
2256
|
SelectPrimitive.Trigger,
|
|
1906
2257
|
{
|
|
1907
2258
|
ref,
|
|
@@ -1912,12 +2263,12 @@ var SelectTrigger = React7.forwardRef(({ className, children, ...props }, ref) =
|
|
|
1912
2263
|
...props,
|
|
1913
2264
|
children: [
|
|
1914
2265
|
children,
|
|
1915
|
-
/* @__PURE__ */
|
|
2266
|
+
/* @__PURE__ */ jsx21(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx21("span", { className: "ml-2 h-4 w-4 shrink-0 opacity-50", children: "\u25BC" }) })
|
|
1916
2267
|
]
|
|
1917
2268
|
}
|
|
1918
2269
|
));
|
|
1919
2270
|
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
1920
|
-
var SelectContent = React7.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */
|
|
2271
|
+
var SelectContent = React7.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx21(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsx21(
|
|
1921
2272
|
SelectPrimitive.Content,
|
|
1922
2273
|
{
|
|
1923
2274
|
ref,
|
|
@@ -1928,7 +2279,7 @@ var SelectContent = React7.forwardRef(({ className, children, position = "popper
|
|
|
1928
2279
|
),
|
|
1929
2280
|
position,
|
|
1930
2281
|
...props,
|
|
1931
|
-
children: /* @__PURE__ */
|
|
2282
|
+
children: /* @__PURE__ */ jsx21(
|
|
1932
2283
|
SelectPrimitive.Viewport,
|
|
1933
2284
|
{
|
|
1934
2285
|
className: cn(
|
|
@@ -1941,7 +2292,7 @@ var SelectContent = React7.forwardRef(({ className, children, position = "popper
|
|
|
1941
2292
|
}
|
|
1942
2293
|
) }));
|
|
1943
2294
|
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
|
1944
|
-
var SelectItem = React7.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */
|
|
2295
|
+
var SelectItem = React7.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs13(
|
|
1945
2296
|
SelectPrimitive.Item,
|
|
1946
2297
|
{
|
|
1947
2298
|
ref,
|
|
@@ -1951,15 +2302,15 @@ var SelectItem = React7.forwardRef(({ className, children, ...props }, ref) => /
|
|
|
1951
2302
|
),
|
|
1952
2303
|
...props,
|
|
1953
2304
|
children: [
|
|
1954
|
-
/* @__PURE__ */
|
|
1955
|
-
/* @__PURE__ */
|
|
2305
|
+
/* @__PURE__ */ jsx21("span", { className: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx21(SelectPrimitive.ItemIndicator, { children: "\u2713" }) }),
|
|
2306
|
+
/* @__PURE__ */ jsx21(SelectPrimitive.ItemText, { children })
|
|
1956
2307
|
]
|
|
1957
2308
|
}
|
|
1958
2309
|
));
|
|
1959
2310
|
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
1960
2311
|
|
|
1961
2312
|
// src/components/wallet/WalletSelector.tsx
|
|
1962
|
-
import { Fragment as Fragment5, jsx as
|
|
2313
|
+
import { Fragment as Fragment5, jsx as jsx22, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1963
2314
|
function WalletSelector(props) {
|
|
1964
2315
|
const {
|
|
1965
2316
|
value,
|
|
@@ -1989,7 +2340,7 @@ function WalletSelector(props) {
|
|
|
1989
2340
|
onWalletChange?.(id, wallets.find((w) => w.id === id || w.walletId === id) ?? null);
|
|
1990
2341
|
};
|
|
1991
2342
|
if (children) {
|
|
1992
|
-
return /* @__PURE__ */
|
|
2343
|
+
return /* @__PURE__ */ jsx22(Fragment5, { children: children({
|
|
1993
2344
|
wallets,
|
|
1994
2345
|
selectedWallet: selected,
|
|
1995
2346
|
selectWallet: (id) => {
|
|
@@ -2002,35 +2353,35 @@ function WalletSelector(props) {
|
|
|
2002
2353
|
}) });
|
|
2003
2354
|
}
|
|
2004
2355
|
if (renderTrigger || renderList) {
|
|
2005
|
-
return /* @__PURE__ */
|
|
2356
|
+
return /* @__PURE__ */ jsxs14("div", { className: cn(className, classNames?.root), "data-cilantro-wallet-selector": true, children: [
|
|
2006
2357
|
renderTrigger?.({ selectedWallet: selected, wallets, isLoading, open: false, setOpen: () => {
|
|
2007
2358
|
} }),
|
|
2008
2359
|
renderList?.({ wallets, selectedWallet: selected, onSelect: handleSelect, isLoading })
|
|
2009
2360
|
] });
|
|
2010
2361
|
}
|
|
2011
2362
|
if (isLoading && useSkeleton) {
|
|
2012
|
-
return /* @__PURE__ */
|
|
2363
|
+
return /* @__PURE__ */ jsx22(
|
|
2013
2364
|
"div",
|
|
2014
2365
|
{
|
|
2015
2366
|
className: cn(className, classNames?.root, classNames?.loading),
|
|
2016
2367
|
"data-cilantro-wallet-selector": true,
|
|
2017
2368
|
"aria-busy": "true",
|
|
2018
2369
|
"aria-live": "polite",
|
|
2019
|
-
children: /* @__PURE__ */
|
|
2370
|
+
children: /* @__PURE__ */ jsx22(
|
|
2020
2371
|
"div",
|
|
2021
2372
|
{
|
|
2022
2373
|
className: cn(
|
|
2023
2374
|
"flex h-9 w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-2",
|
|
2024
2375
|
classNames?.trigger
|
|
2025
2376
|
),
|
|
2026
|
-
children: /* @__PURE__ */
|
|
2377
|
+
children: /* @__PURE__ */ jsx22(Skeleton, { className: cn("h-4 flex-1 rounded", classNames?.skeleton) })
|
|
2027
2378
|
}
|
|
2028
2379
|
)
|
|
2029
2380
|
}
|
|
2030
2381
|
);
|
|
2031
2382
|
}
|
|
2032
2383
|
if (isEmpty) {
|
|
2033
|
-
return /* @__PURE__ */
|
|
2384
|
+
return /* @__PURE__ */ jsxs14(
|
|
2034
2385
|
"div",
|
|
2035
2386
|
{
|
|
2036
2387
|
className: cn(
|
|
@@ -2040,24 +2391,24 @@ function WalletSelector(props) {
|
|
|
2040
2391
|
),
|
|
2041
2392
|
"data-cilantro-wallet-selector": true,
|
|
2042
2393
|
children: [
|
|
2043
|
-
/* @__PURE__ */
|
|
2044
|
-
/* @__PURE__ */
|
|
2394
|
+
/* @__PURE__ */ jsx22("p", { className: "font-medium text-foreground", children: "No wallets" }),
|
|
2395
|
+
/* @__PURE__ */ jsx22("p", { className: "mt-1", children: "Wallets are created by the platform when you sign in. If you just logged in, try refreshing." })
|
|
2045
2396
|
]
|
|
2046
2397
|
}
|
|
2047
2398
|
);
|
|
2048
2399
|
}
|
|
2049
|
-
return /* @__PURE__ */
|
|
2050
|
-
/* @__PURE__ */
|
|
2051
|
-
/* @__PURE__ */
|
|
2400
|
+
return /* @__PURE__ */ jsx22("div", { className: cn(className, classNames?.root), "data-cilantro-wallet-selector": true, children: /* @__PURE__ */ jsxs14(Select, { value: effectiveValue || void 0, onValueChange: handleValueChange, disabled: isLoading, children: [
|
|
2401
|
+
/* @__PURE__ */ jsx22(SelectTrigger, { className: classNames?.trigger, "aria-label": "Select wallet", children: /* @__PURE__ */ jsx22(SelectValue, { placeholder: isLoading ? "Loading..." : placeholder }) }),
|
|
2402
|
+
/* @__PURE__ */ jsx22(SelectContent, { className: classNames?.content, children: wallets.map((w) => {
|
|
2052
2403
|
const id = w.id ?? w.walletId;
|
|
2053
|
-
return /* @__PURE__ */
|
|
2404
|
+
return /* @__PURE__ */ jsx22(SelectItem, { value: id, className: classNames?.item, children: w.walletName || id }, id);
|
|
2054
2405
|
}) })
|
|
2055
2406
|
] }) });
|
|
2056
2407
|
}
|
|
2057
2408
|
|
|
2058
2409
|
// src/components/wallet/WalletAddress.tsx
|
|
2059
|
-
import { useState as
|
|
2060
|
-
import { jsx as
|
|
2410
|
+
import { useState as useState15 } from "react";
|
|
2411
|
+
import { jsx as jsx23, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2061
2412
|
function truncateAddress(addr, chars = 4) {
|
|
2062
2413
|
if (addr.length <= chars * 2 + 3) return addr;
|
|
2063
2414
|
return `${addr.slice(0, chars)}...${addr.slice(-chars)}`;
|
|
@@ -2068,7 +2419,7 @@ function WalletAddress({
|
|
|
2068
2419
|
copyable = false,
|
|
2069
2420
|
className
|
|
2070
2421
|
}) {
|
|
2071
|
-
const [copied, setCopied] =
|
|
2422
|
+
const [copied, setCopied] = useState15(false);
|
|
2072
2423
|
const display = short ? truncateAddress(address) : address;
|
|
2073
2424
|
const handleCopy = async () => {
|
|
2074
2425
|
try {
|
|
@@ -2078,9 +2429,9 @@ function WalletAddress({
|
|
|
2078
2429
|
} catch {
|
|
2079
2430
|
}
|
|
2080
2431
|
};
|
|
2081
|
-
return /* @__PURE__ */
|
|
2082
|
-
/* @__PURE__ */
|
|
2083
|
-
copyable && /* @__PURE__ */
|
|
2432
|
+
return /* @__PURE__ */ jsxs15("span", { className: cn("inline-flex items-center gap-2", className), "data-cilantro-wallet-address": true, children: [
|
|
2433
|
+
/* @__PURE__ */ jsx23("code", { className: "text-sm font-mono", children: display }),
|
|
2434
|
+
copyable && /* @__PURE__ */ jsx23(
|
|
2084
2435
|
Button,
|
|
2085
2436
|
{
|
|
2086
2437
|
type: "button",
|
|
@@ -2096,19 +2447,19 @@ function WalletAddress({
|
|
|
2096
2447
|
}
|
|
2097
2448
|
|
|
2098
2449
|
// src/components/wallet/WalletBalance.tsx
|
|
2099
|
-
import { useState as
|
|
2450
|
+
import { useState as useState16, useEffect as useEffect5 } from "react";
|
|
2100
2451
|
import { getAssets } from "cilantro-sdk/wallet";
|
|
2101
|
-
import { jsx as
|
|
2452
|
+
import { jsx as jsx24, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2102
2453
|
function WalletBalance({
|
|
2103
2454
|
walletId,
|
|
2104
2455
|
showTokens = false,
|
|
2105
2456
|
className
|
|
2106
2457
|
}) {
|
|
2107
2458
|
const { jwt } = useCilantroContext();
|
|
2108
|
-
const [loading, setLoading] =
|
|
2109
|
-
const [solBalance, setSolBalance] =
|
|
2110
|
-
const [tokens, setTokens] =
|
|
2111
|
-
const [error, setError] =
|
|
2459
|
+
const [loading, setLoading] = useState16(true);
|
|
2460
|
+
const [solBalance, setSolBalance] = useState16(null);
|
|
2461
|
+
const [tokens, setTokens] = useState16([]);
|
|
2462
|
+
const [error, setError] = useState16(null);
|
|
2112
2463
|
useEffect5(() => {
|
|
2113
2464
|
if (!walletId || !jwt) {
|
|
2114
2465
|
setSolBalance(null);
|
|
@@ -2146,15 +2497,15 @@ function WalletBalance({
|
|
|
2146
2497
|
};
|
|
2147
2498
|
}, [walletId, jwt, showTokens]);
|
|
2148
2499
|
if (loading) {
|
|
2149
|
-
return /* @__PURE__ */
|
|
2500
|
+
return /* @__PURE__ */ jsx24("div", { className: cn(className), "data-cilantro-wallet-balance": true, children: /* @__PURE__ */ jsx24(Skeleton, { className: "h-5 w-24 rounded" }) });
|
|
2150
2501
|
}
|
|
2151
2502
|
if (error) {
|
|
2152
|
-
return /* @__PURE__ */
|
|
2503
|
+
return /* @__PURE__ */ jsx24("div", { className: cn("text-sm text-destructive", className), "data-cilantro-wallet-balance": true, role: "alert", children: error });
|
|
2153
2504
|
}
|
|
2154
2505
|
const solDisplay = solBalance != null ? `${Number(solBalance) / 1e9} SOL` : "\u2014";
|
|
2155
|
-
return /* @__PURE__ */
|
|
2156
|
-
/* @__PURE__ */
|
|
2157
|
-
showTokens && tokens.length > 0 && /* @__PURE__ */
|
|
2506
|
+
return /* @__PURE__ */ jsxs16("div", { className: cn("text-sm", className), "data-cilantro-wallet-balance": true, children: [
|
|
2507
|
+
/* @__PURE__ */ jsx24("span", { className: "font-medium", children: solDisplay }),
|
|
2508
|
+
showTokens && tokens.length > 0 && /* @__PURE__ */ jsx24("ul", { className: "mt-1 space-y-0.5 text-muted-foreground", children: tokens.map((t, i) => /* @__PURE__ */ jsxs16("li", { children: [
|
|
2158
2509
|
t.symbol ?? t.mint ?? "Token",
|
|
2159
2510
|
": ",
|
|
2160
2511
|
t.balance ?? "\u2014"
|
|
@@ -2163,8 +2514,8 @@ function WalletBalance({
|
|
|
2163
2514
|
}
|
|
2164
2515
|
|
|
2165
2516
|
// src/components/transactions/SendSOLForm.tsx
|
|
2166
|
-
import { useState as
|
|
2167
|
-
import { jsx as
|
|
2517
|
+
import { useState as useState17 } from "react";
|
|
2518
|
+
import { jsx as jsx25, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2168
2519
|
function SendSOLForm({
|
|
2169
2520
|
walletId,
|
|
2170
2521
|
signerId,
|
|
@@ -2174,9 +2525,9 @@ function SendSOLForm({
|
|
|
2174
2525
|
className
|
|
2175
2526
|
}) {
|
|
2176
2527
|
const { sendSOL, isPending, error } = useSendTransaction(walletId, signerId, signerType);
|
|
2177
|
-
const [recipientAddress, setRecipientAddress] =
|
|
2178
|
-
const [amountLamports, setAmountLamports] =
|
|
2179
|
-
const [submitError, setSubmitError] =
|
|
2528
|
+
const [recipientAddress, setRecipientAddress] = useState17("");
|
|
2529
|
+
const [amountLamports, setAmountLamports] = useState17("");
|
|
2530
|
+
const [submitError, setSubmitError] = useState17(null);
|
|
2180
2531
|
const handleSubmit = async (e) => {
|
|
2181
2532
|
e.preventDefault();
|
|
2182
2533
|
setSubmitError(null);
|
|
@@ -2196,10 +2547,10 @@ function SendSOLForm({
|
|
|
2196
2547
|
onError?.(err instanceof Error ? err : new Error(message));
|
|
2197
2548
|
}
|
|
2198
2549
|
};
|
|
2199
|
-
return /* @__PURE__ */
|
|
2200
|
-
/* @__PURE__ */
|
|
2201
|
-
/* @__PURE__ */
|
|
2202
|
-
/* @__PURE__ */
|
|
2550
|
+
return /* @__PURE__ */ jsxs17("form", { onSubmit: handleSubmit, className: cn("space-y-4", className), "data-cilantro-send-sol": true, children: [
|
|
2551
|
+
/* @__PURE__ */ jsxs17("div", { className: "space-y-2", children: [
|
|
2552
|
+
/* @__PURE__ */ jsx25(Label, { htmlFor: "cilantro-send-sol-recipient", children: "Recipient address" }),
|
|
2553
|
+
/* @__PURE__ */ jsx25(
|
|
2203
2554
|
Input,
|
|
2204
2555
|
{
|
|
2205
2556
|
id: "cilantro-send-sol-recipient",
|
|
@@ -2212,9 +2563,9 @@ function SendSOLForm({
|
|
|
2212
2563
|
}
|
|
2213
2564
|
)
|
|
2214
2565
|
] }),
|
|
2215
|
-
/* @__PURE__ */
|
|
2216
|
-
/* @__PURE__ */
|
|
2217
|
-
/* @__PURE__ */
|
|
2566
|
+
/* @__PURE__ */ jsxs17("div", { className: "space-y-2", children: [
|
|
2567
|
+
/* @__PURE__ */ jsx25(Label, { htmlFor: "cilantro-send-sol-amount", children: "Amount (lamports)" }),
|
|
2568
|
+
/* @__PURE__ */ jsx25(
|
|
2218
2569
|
Input,
|
|
2219
2570
|
{
|
|
2220
2571
|
id: "cilantro-send-sol-amount",
|
|
@@ -2228,14 +2579,14 @@ function SendSOLForm({
|
|
|
2228
2579
|
}
|
|
2229
2580
|
)
|
|
2230
2581
|
] }),
|
|
2231
|
-
(error || submitError) && /* @__PURE__ */
|
|
2232
|
-
/* @__PURE__ */
|
|
2582
|
+
(error || submitError) && /* @__PURE__ */ jsx25("div", { className: "rounded-md border border-destructive/50 bg-destructive/10 px-3 py-2 text-sm text-destructive", role: "alert", children: submitError ?? error }),
|
|
2583
|
+
/* @__PURE__ */ jsx25(Button, { type: "submit", disabled: isPending || !recipientAddress.trim() || !amountLamports, children: isPending ? "Sending..." : "Send SOL" })
|
|
2233
2584
|
] });
|
|
2234
2585
|
}
|
|
2235
2586
|
|
|
2236
2587
|
// src/components/transactions/SendSPLForm.tsx
|
|
2237
|
-
import { useState as
|
|
2238
|
-
import { jsx as
|
|
2588
|
+
import { useState as useState18 } from "react";
|
|
2589
|
+
import { jsx as jsx26, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2239
2590
|
function SendSPLForm({
|
|
2240
2591
|
walletId,
|
|
2241
2592
|
signerId,
|
|
@@ -2246,10 +2597,10 @@ function SendSPLForm({
|
|
|
2246
2597
|
className
|
|
2247
2598
|
}) {
|
|
2248
2599
|
const { sendSPL, isPending, error } = useSendTransaction(walletId, signerId, signerType);
|
|
2249
|
-
const [mintAddress, setMintAddress] =
|
|
2250
|
-
const [recipientAddress, setRecipientAddress] =
|
|
2251
|
-
const [amount, setAmount] =
|
|
2252
|
-
const [submitError, setSubmitError] =
|
|
2600
|
+
const [mintAddress, setMintAddress] = useState18(initialMint ?? "");
|
|
2601
|
+
const [recipientAddress, setRecipientAddress] = useState18("");
|
|
2602
|
+
const [amount, setAmount] = useState18("");
|
|
2603
|
+
const [submitError, setSubmitError] = useState18(null);
|
|
2253
2604
|
const handleSubmit = async (e) => {
|
|
2254
2605
|
e.preventDefault();
|
|
2255
2606
|
setSubmitError(null);
|
|
@@ -2273,10 +2624,10 @@ function SendSPLForm({
|
|
|
2273
2624
|
onError?.(err instanceof Error ? err : new Error(message));
|
|
2274
2625
|
}
|
|
2275
2626
|
};
|
|
2276
|
-
return /* @__PURE__ */
|
|
2277
|
-
/* @__PURE__ */
|
|
2278
|
-
/* @__PURE__ */
|
|
2279
|
-
/* @__PURE__ */
|
|
2627
|
+
return /* @__PURE__ */ jsxs18("form", { onSubmit: handleSubmit, className: cn("space-y-4", className), "data-cilantro-send-spl": true, children: [
|
|
2628
|
+
/* @__PURE__ */ jsxs18("div", { className: "space-y-2", children: [
|
|
2629
|
+
/* @__PURE__ */ jsx26(Label, { htmlFor: "cilantro-send-spl-mint", children: "Mint address" }),
|
|
2630
|
+
/* @__PURE__ */ jsx26(
|
|
2280
2631
|
Input,
|
|
2281
2632
|
{
|
|
2282
2633
|
id: "cilantro-send-spl-mint",
|
|
@@ -2289,9 +2640,9 @@ function SendSPLForm({
|
|
|
2289
2640
|
}
|
|
2290
2641
|
)
|
|
2291
2642
|
] }),
|
|
2292
|
-
/* @__PURE__ */
|
|
2293
|
-
/* @__PURE__ */
|
|
2294
|
-
/* @__PURE__ */
|
|
2643
|
+
/* @__PURE__ */ jsxs18("div", { className: "space-y-2", children: [
|
|
2644
|
+
/* @__PURE__ */ jsx26(Label, { htmlFor: "cilantro-send-spl-recipient", children: "Recipient address" }),
|
|
2645
|
+
/* @__PURE__ */ jsx26(
|
|
2295
2646
|
Input,
|
|
2296
2647
|
{
|
|
2297
2648
|
id: "cilantro-send-spl-recipient",
|
|
@@ -2304,9 +2655,9 @@ function SendSPLForm({
|
|
|
2304
2655
|
}
|
|
2305
2656
|
)
|
|
2306
2657
|
] }),
|
|
2307
|
-
/* @__PURE__ */
|
|
2308
|
-
/* @__PURE__ */
|
|
2309
|
-
/* @__PURE__ */
|
|
2658
|
+
/* @__PURE__ */ jsxs18("div", { className: "space-y-2", children: [
|
|
2659
|
+
/* @__PURE__ */ jsx26(Label, { htmlFor: "cilantro-send-spl-amount", children: "Amount" }),
|
|
2660
|
+
/* @__PURE__ */ jsx26(
|
|
2310
2661
|
Input,
|
|
2311
2662
|
{
|
|
2312
2663
|
id: "cilantro-send-spl-amount",
|
|
@@ -2321,13 +2672,13 @@ function SendSPLForm({
|
|
|
2321
2672
|
}
|
|
2322
2673
|
)
|
|
2323
2674
|
] }),
|
|
2324
|
-
(error || submitError) && /* @__PURE__ */
|
|
2325
|
-
/* @__PURE__ */
|
|
2675
|
+
(error || submitError) && /* @__PURE__ */ jsx26("div", { className: "rounded-md border border-destructive/50 bg-destructive/10 px-3 py-2 text-sm text-destructive", role: "alert", children: submitError ?? error }),
|
|
2676
|
+
/* @__PURE__ */ jsx26(Button, { type: "submit", disabled: isPending || !mintAddress.trim() || !recipientAddress.trim() || !amount, children: isPending ? "Sending..." : "Send SPL" })
|
|
2326
2677
|
] });
|
|
2327
2678
|
}
|
|
2328
2679
|
|
|
2329
2680
|
// src/components/transactions/TransactionStatus.tsx
|
|
2330
|
-
import { jsx as
|
|
2681
|
+
import { jsx as jsx27, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2331
2682
|
var EXPLORER_URL = {
|
|
2332
2683
|
"mainnet-beta": "https://explorer.solana.com",
|
|
2333
2684
|
devnet: "https://explorer.solana.com/?cluster=devnet",
|
|
@@ -2340,9 +2691,9 @@ function TransactionStatus({
|
|
|
2340
2691
|
}) {
|
|
2341
2692
|
const base = EXPLORER_URL[cluster] ?? EXPLORER_URL["mainnet-beta"];
|
|
2342
2693
|
const href = `${base}/tx/${signature}`;
|
|
2343
|
-
return /* @__PURE__ */
|
|
2344
|
-
/* @__PURE__ */
|
|
2345
|
-
/* @__PURE__ */
|
|
2694
|
+
return /* @__PURE__ */ jsxs19("div", { className: cn("text-sm", className), "data-cilantro-transaction-status": true, children: [
|
|
2695
|
+
/* @__PURE__ */ jsx27("span", { className: "text-muted-foreground", children: "Transaction: " }),
|
|
2696
|
+
/* @__PURE__ */ jsxs19(
|
|
2346
2697
|
"a",
|
|
2347
2698
|
{
|
|
2348
2699
|
href,
|
|
@@ -2360,17 +2711,17 @@ function TransactionStatus({
|
|
|
2360
2711
|
}
|
|
2361
2712
|
|
|
2362
2713
|
// src/components/transactions/TransactionHistory.tsx
|
|
2363
|
-
import { useState as
|
|
2364
|
-
import { jsx as
|
|
2714
|
+
import { useState as useState19, useEffect as useEffect6 } from "react";
|
|
2715
|
+
import { jsx as jsx28 } from "react/jsx-runtime";
|
|
2365
2716
|
function TransactionHistory({
|
|
2366
2717
|
walletId,
|
|
2367
2718
|
pageSize = 10,
|
|
2368
2719
|
className
|
|
2369
2720
|
}) {
|
|
2370
2721
|
const { jwt } = useCilantroContext();
|
|
2371
|
-
const [loading, setLoading] =
|
|
2372
|
-
const [signatures, setSignatures] =
|
|
2373
|
-
const [error, setError] =
|
|
2722
|
+
const [loading, setLoading] = useState19(true);
|
|
2723
|
+
const [signatures, setSignatures] = useState19([]);
|
|
2724
|
+
const [error, setError] = useState19(null);
|
|
2374
2725
|
useEffect6(() => {
|
|
2375
2726
|
if (!walletId || !jwt) {
|
|
2376
2727
|
setSignatures([]);
|
|
@@ -2398,20 +2749,20 @@ function TransactionHistory({
|
|
|
2398
2749
|
};
|
|
2399
2750
|
}, [walletId, jwt, pageSize]);
|
|
2400
2751
|
if (loading) {
|
|
2401
|
-
return /* @__PURE__ */
|
|
2752
|
+
return /* @__PURE__ */ jsx28("div", { className: cn("text-sm text-muted-foreground", className), "data-cilantro-transaction-history": true, children: "Loading..." });
|
|
2402
2753
|
}
|
|
2403
2754
|
if (error) {
|
|
2404
|
-
return /* @__PURE__ */
|
|
2755
|
+
return /* @__PURE__ */ jsx28("div", { className: cn("text-sm text-destructive", className), "data-cilantro-transaction-history": true, role: "alert", children: error });
|
|
2405
2756
|
}
|
|
2406
2757
|
if (signatures.length === 0) {
|
|
2407
|
-
return /* @__PURE__ */
|
|
2758
|
+
return /* @__PURE__ */ jsx28("div", { className: cn("text-sm text-muted-foreground", className), "data-cilantro-transaction-history": true, children: "No recent transactions." });
|
|
2408
2759
|
}
|
|
2409
|
-
return /* @__PURE__ */
|
|
2760
|
+
return /* @__PURE__ */ jsx28("ul", { className: cn("space-y-2", className), "data-cilantro-transaction-history": true, role: "list", children: signatures.map((sig) => /* @__PURE__ */ jsx28("li", { children: /* @__PURE__ */ jsx28(TransactionStatus, { signature: sig }) }, sig)) });
|
|
2410
2761
|
}
|
|
2411
2762
|
|
|
2412
2763
|
// src/components/layout/CilantroConnect.tsx
|
|
2413
|
-
import { useState as
|
|
2414
|
-
import { jsx as
|
|
2764
|
+
import { useState as useState20 } from "react";
|
|
2765
|
+
import { jsx as jsx29, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
2415
2766
|
function CilantroConnect({
|
|
2416
2767
|
onConnect,
|
|
2417
2768
|
onDisconnect,
|
|
@@ -2419,13 +2770,13 @@ function CilantroConnect({
|
|
|
2419
2770
|
}) {
|
|
2420
2771
|
const { isAuthenticated } = useAuth();
|
|
2421
2772
|
const { wallet, wallets, createWallet, selectWallet, isLoading: walletLoading } = useWallet();
|
|
2422
|
-
const [walletId, setWalletId] =
|
|
2423
|
-
const [step, setStep] =
|
|
2773
|
+
const [walletId, setWalletId] = useState20(null);
|
|
2774
|
+
const [step, setStep] = useState20("auth");
|
|
2424
2775
|
if (!isAuthenticated) {
|
|
2425
|
-
return /* @__PURE__ */
|
|
2776
|
+
return /* @__PURE__ */ jsx29("div", { className: cn(className), "data-cilantro-connect": true, children: /* @__PURE__ */ jsx29(LoginForm, { onSuccess: () => setStep("wallet") }) });
|
|
2426
2777
|
}
|
|
2427
2778
|
if (step === "wallet" && wallets.length === 0 && !walletLoading) {
|
|
2428
|
-
return /* @__PURE__ */
|
|
2779
|
+
return /* @__PURE__ */ jsx29("div", { className: cn(className), "data-cilantro-connect": true, children: /* @__PURE__ */ jsx29(
|
|
2429
2780
|
CreateWalletForm,
|
|
2430
2781
|
{
|
|
2431
2782
|
onCreated: (res) => {
|
|
@@ -2441,9 +2792,9 @@ function CilantroConnect({
|
|
|
2441
2792
|
}
|
|
2442
2793
|
if (step === "signer" && walletId) {
|
|
2443
2794
|
const currentWallet = wallet ?? wallets.find((w) => (w.id ?? w.walletId) === walletId);
|
|
2444
|
-
return /* @__PURE__ */
|
|
2445
|
-
/* @__PURE__ */
|
|
2446
|
-
/* @__PURE__ */
|
|
2795
|
+
return /* @__PURE__ */ jsxs20("div", { className: cn("space-y-4", className), "data-cilantro-connect": true, children: [
|
|
2796
|
+
/* @__PURE__ */ jsx29("p", { className: "text-sm text-muted-foreground", children: "Add a signer to your wallet" }),
|
|
2797
|
+
/* @__PURE__ */ jsx29(
|
|
2447
2798
|
CreateEmailSignerForm,
|
|
2448
2799
|
{
|
|
2449
2800
|
walletId,
|
|
@@ -2456,7 +2807,7 @@ function CilantroConnect({
|
|
|
2456
2807
|
}
|
|
2457
2808
|
}
|
|
2458
2809
|
),
|
|
2459
|
-
/* @__PURE__ */
|
|
2810
|
+
/* @__PURE__ */ jsx29(
|
|
2460
2811
|
AddPasskeyButton,
|
|
2461
2812
|
{
|
|
2462
2813
|
walletId,
|
|
@@ -2471,9 +2822,9 @@ function CilantroConnect({
|
|
|
2471
2822
|
] });
|
|
2472
2823
|
}
|
|
2473
2824
|
if (wallet && step === "done") {
|
|
2474
|
-
return /* @__PURE__ */
|
|
2475
|
-
/* @__PURE__ */
|
|
2476
|
-
onDisconnect && /* @__PURE__ */
|
|
2825
|
+
return /* @__PURE__ */ jsxs20("div", { className: cn(className), "data-cilantro-connect": true, children: [
|
|
2826
|
+
/* @__PURE__ */ jsx29("p", { className: "text-sm text-muted-foreground", children: "Connected" }),
|
|
2827
|
+
onDisconnect && /* @__PURE__ */ jsx29(
|
|
2477
2828
|
"button",
|
|
2478
2829
|
{
|
|
2479
2830
|
type: "button",
|
|
@@ -2489,11 +2840,11 @@ function CilantroConnect({
|
|
|
2489
2840
|
] });
|
|
2490
2841
|
}
|
|
2491
2842
|
if (walletLoading) {
|
|
2492
|
-
return /* @__PURE__ */
|
|
2843
|
+
return /* @__PURE__ */ jsx29("div", { className: cn("text-sm text-muted-foreground", className), "data-cilantro-connect": true, children: "Loading..." });
|
|
2493
2844
|
}
|
|
2494
|
-
return /* @__PURE__ */
|
|
2495
|
-
/* @__PURE__ */
|
|
2496
|
-
/* @__PURE__ */
|
|
2845
|
+
return /* @__PURE__ */ jsxs20("div", { className: cn(className), "data-cilantro-connect": true, children: [
|
|
2846
|
+
/* @__PURE__ */ jsx29("p", { className: "text-sm text-muted-foreground", children: "Set up your wallet" }),
|
|
2847
|
+
/* @__PURE__ */ jsx29(
|
|
2497
2848
|
CreateWalletForm,
|
|
2498
2849
|
{
|
|
2499
2850
|
onCreated: (res) => {
|
|
@@ -2510,24 +2861,24 @@ function CilantroConnect({
|
|
|
2510
2861
|
}
|
|
2511
2862
|
|
|
2512
2863
|
// src/components/layout/LoadingOverlay.tsx
|
|
2513
|
-
import { Fragment as Fragment6, jsx as
|
|
2864
|
+
import { Fragment as Fragment6, jsx as jsx30, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
2514
2865
|
function LoadingOverlay({
|
|
2515
2866
|
isLoading,
|
|
2516
2867
|
message,
|
|
2517
2868
|
children,
|
|
2518
2869
|
className
|
|
2519
2870
|
}) {
|
|
2520
|
-
if (!isLoading) return /* @__PURE__ */
|
|
2521
|
-
return /* @__PURE__ */
|
|
2522
|
-
/* @__PURE__ */
|
|
2871
|
+
if (!isLoading) return /* @__PURE__ */ jsx30(Fragment6, { children });
|
|
2872
|
+
return /* @__PURE__ */ jsxs21("div", { className: cn("relative", className), "data-cilantro-loading-overlay": true, children: [
|
|
2873
|
+
/* @__PURE__ */ jsx30(
|
|
2523
2874
|
"div",
|
|
2524
2875
|
{
|
|
2525
2876
|
className: "absolute inset-0 z-10 flex items-center justify-center bg-background/80",
|
|
2526
2877
|
"aria-busy": "true",
|
|
2527
2878
|
"aria-live": "polite",
|
|
2528
|
-
children: /* @__PURE__ */
|
|
2529
|
-
/* @__PURE__ */
|
|
2530
|
-
message && /* @__PURE__ */
|
|
2879
|
+
children: /* @__PURE__ */ jsxs21("div", { className: "flex flex-col items-center gap-2", children: [
|
|
2880
|
+
/* @__PURE__ */ jsx30("div", { className: "h-8 w-8 animate-spin rounded-full border-2 border-primary border-t-transparent" }),
|
|
2881
|
+
message && /* @__PURE__ */ jsx30("p", { className: "text-sm text-muted-foreground", children: message })
|
|
2531
2882
|
] })
|
|
2532
2883
|
}
|
|
2533
2884
|
),
|
|
@@ -2537,7 +2888,7 @@ function LoadingOverlay({
|
|
|
2537
2888
|
|
|
2538
2889
|
// src/components/layout/ErrorBoundary.tsx
|
|
2539
2890
|
import { Component } from "react";
|
|
2540
|
-
import { jsx as
|
|
2891
|
+
import { jsx as jsx31, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
2541
2892
|
var ErrorBoundary = class extends Component {
|
|
2542
2893
|
constructor() {
|
|
2543
2894
|
super(...arguments);
|
|
@@ -2558,16 +2909,16 @@ var ErrorBoundary = class extends Component {
|
|
|
2558
2909
|
if (this.props.fallback) {
|
|
2559
2910
|
return this.props.fallback;
|
|
2560
2911
|
}
|
|
2561
|
-
return /* @__PURE__ */
|
|
2912
|
+
return /* @__PURE__ */ jsxs22(
|
|
2562
2913
|
"div",
|
|
2563
2914
|
{
|
|
2564
2915
|
className: "rounded-md border border-destructive/50 bg-destructive/10 p-4 text-sm text-destructive",
|
|
2565
2916
|
"data-cilantro-error-boundary": true,
|
|
2566
2917
|
role: "alert",
|
|
2567
2918
|
children: [
|
|
2568
|
-
/* @__PURE__ */
|
|
2569
|
-
/* @__PURE__ */
|
|
2570
|
-
this.props.onRetry && /* @__PURE__ */
|
|
2919
|
+
/* @__PURE__ */ jsx31("p", { className: "font-medium", children: "Something went wrong" }),
|
|
2920
|
+
/* @__PURE__ */ jsx31("p", { className: "mt-1 text-muted-foreground", children: this.state.error.message }),
|
|
2921
|
+
this.props.onRetry && /* @__PURE__ */ jsx31(Button, { type: "button", variant: "outline", size: "sm", className: "mt-3", onClick: this.handleRetry, children: "Retry" })
|
|
2571
2922
|
]
|
|
2572
2923
|
}
|
|
2573
2924
|
);
|
|
@@ -2578,7 +2929,7 @@ var ErrorBoundary = class extends Component {
|
|
|
2578
2929
|
|
|
2579
2930
|
// src/ui/theme-provider.tsx
|
|
2580
2931
|
import * as React8 from "react";
|
|
2581
|
-
import { Fragment as Fragment7, jsx as
|
|
2932
|
+
import { Fragment as Fragment7, jsx as jsx32, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
2582
2933
|
var DEFAULT_THEME_CSS = `
|
|
2583
2934
|
:root,[data-theme="light"]{--background:0 0% 100%;--foreground:222.2 84% 4.9%;--primary:222.2 47.4% 11.2%;--primary-foreground:210 40% 98%;--muted:210 40% 96.1%;--muted-foreground:215.4 16.3% 46.9%;--border:214.3 31.8% 91.4%;--input:214.3 31.8% 91.4%;--ring:222.2 84% 4.9%;--destructive:0 84.2% 60.2%;--destructive-foreground:210 40% 98%;--accent:210 40% 96.1%;--accent-foreground:222.2 47.4% 11.2%;--popover:0 0% 100%;--popover-foreground:222.2 84% 4.9%;--card:0 0% 100%;--card-foreground:222.2 84% 4.9%}
|
|
2584
2935
|
[data-theme="dark"]{--background:222.2 84% 4.9%;--foreground:210 40% 98%;--primary:210 40% 98%;--primary-foreground:222.2 47.4% 11.2%;--muted:217.2 32.6% 17.5%;--muted-foreground:215 20.2% 65.1%;--border:217.2 32.6% 17.5%;--input:217.2 32.6% 17.5%;--ring:212.7 26.8% 83.9%;--destructive:0 62.8% 30.6%;--destructive-foreground:210 40% 98%;--accent:217.2 32.6% 17.5%;--accent-foreground:210 40% 98%;--popover:222.2 84% 4.9%;--popover-foreground:210 40% 98%;--card:222.2 84% 4.9%;--card-foreground:210 40% 98%}
|
|
@@ -2624,15 +2975,15 @@ function ThemeProvider({
|
|
|
2624
2975
|
mql.addEventListener("change", listener);
|
|
2625
2976
|
return () => mql.removeEventListener("change", listener);
|
|
2626
2977
|
}, [theme, storageKey]);
|
|
2627
|
-
return /* @__PURE__ */
|
|
2628
|
-
injectStyles && /* @__PURE__ */
|
|
2978
|
+
return /* @__PURE__ */ jsxs23(Fragment7, { children: [
|
|
2979
|
+
injectStyles && /* @__PURE__ */ jsx32(
|
|
2629
2980
|
"style",
|
|
2630
2981
|
{
|
|
2631
2982
|
dangerouslySetInnerHTML: { __html: DEFAULT_THEME_CSS },
|
|
2632
2983
|
"data-cilantro-theme-styles": true
|
|
2633
2984
|
}
|
|
2634
2985
|
),
|
|
2635
|
-
/* @__PURE__ */
|
|
2986
|
+
/* @__PURE__ */ jsx32(
|
|
2636
2987
|
"div",
|
|
2637
2988
|
{
|
|
2638
2989
|
className: cn(className),
|
|
@@ -2976,7 +3327,7 @@ async function submitSignedTransaction(walletId, signedTransactionBase64) {
|
|
|
2976
3327
|
async function handlePasskeyTransaction(walletId, signerId, transaction, connection) {
|
|
2977
3328
|
if (!connection) {
|
|
2978
3329
|
throw new Error(
|
|
2979
|
-
"Connection is required for passkey sign-and-send. Pass the connection from your Solana config
|
|
3330
|
+
"Connection is required for passkey sign-and-send. Pass the connection from your Solana config."
|
|
2980
3331
|
);
|
|
2981
3332
|
}
|
|
2982
3333
|
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash("confirmed");
|
|
@@ -3128,6 +3479,7 @@ async function getWalletData(walletId) {
|
|
|
3128
3479
|
export {
|
|
3129
3480
|
AddPasskeyButton,
|
|
3130
3481
|
AuthGuard,
|
|
3482
|
+
AuthShell,
|
|
3131
3483
|
CilantroConnect,
|
|
3132
3484
|
CilantroContextProvider,
|
|
3133
3485
|
CilantroProvider,
|
|
@@ -3139,6 +3491,7 @@ export {
|
|
|
3139
3491
|
LoadingOverlay,
|
|
3140
3492
|
LoginForm,
|
|
3141
3493
|
LogoutButton,
|
|
3494
|
+
RegisterForm,
|
|
3142
3495
|
SIGNER_TYPES,
|
|
3143
3496
|
SendSOLForm,
|
|
3144
3497
|
SendSPLForm,
|
|
@@ -3158,7 +3511,9 @@ export {
|
|
|
3158
3511
|
extractErrorMessage,
|
|
3159
3512
|
extractResponseData,
|
|
3160
3513
|
getSignerPublicKey,
|
|
3514
|
+
getWalletAddress,
|
|
3161
3515
|
getWalletData,
|
|
3516
|
+
getWalletId,
|
|
3162
3517
|
isAuthError,
|
|
3163
3518
|
isJwtExpired,
|
|
3164
3519
|
normalizeSigner,
|
|
@@ -3172,6 +3527,7 @@ export {
|
|
|
3172
3527
|
useCilantroContext,
|
|
3173
3528
|
useExternalWallet,
|
|
3174
3529
|
usePasskey,
|
|
3530
|
+
useReturnUrl,
|
|
3175
3531
|
useSendTransaction,
|
|
3176
3532
|
useSigners,
|
|
3177
3533
|
useWallet,
|