@agg-build/auth 1.0.0

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.
@@ -0,0 +1,535 @@
1
+ import {
2
+ normalizeAuthError,
3
+ shortenAddress,
4
+ shortenProfileLabel,
5
+ toError
6
+ } from "./chunk-BVV6GEOL.mjs";
7
+ import {
8
+ __async,
9
+ __spreadProps,
10
+ __spreadValues
11
+ } from "./chunk-AXBFBHS2.mjs";
12
+
13
+ // src/connect-button/index.tsx
14
+ import { useEffect as useEffect2, useMemo as useMemo2, useState as useState2 } from "react";
15
+ import { AuthConnectButtonView } from "@agg-build/ui";
16
+ import {
17
+ AUTH_CHOOSER_OPEN_EVENT,
18
+ getWalletAddressFromUserProfile as getWalletAddressFromUserProfile2,
19
+ parseEmail,
20
+ useAggAuthContext as useAggAuthContext2,
21
+ useAggBalanceState,
22
+ useGeoBlock
23
+ } from "@agg-build/hooks";
24
+
25
+ // src/core/context.tsx
26
+ import {
27
+ createContext,
28
+ useCallback,
29
+ useContext,
30
+ useEffect,
31
+ useMemo,
32
+ useRef,
33
+ useState
34
+ } from "react";
35
+ import { useAggAuthContext, TurnstileChallengeError } from "@agg-build/hooks";
36
+
37
+ // src/core/methods.ts
38
+ var getAvailableAuthMethods = (methods) => {
39
+ return methods.filter((method) => method.isAvailable);
40
+ };
41
+
42
+ // src/core/context.tsx
43
+ import { jsx } from "react/jsx-runtime";
44
+ var AggAuthFlowContext = createContext(null);
45
+ var AggAuthProvider = ({
46
+ autoHandleAuthCallback = true,
47
+ children,
48
+ methods
49
+ }) => {
50
+ const auth = useAggAuthContext();
51
+ const handledCallbackRef = useRef(false);
52
+ const [activeMethodId, setActiveMethodId] = useState(null);
53
+ const [selectedMethodId, setSelectedMethodId] = useState(null);
54
+ const [error, setError] = useState(null);
55
+ const [notice, setNotice] = useState(null);
56
+ const [challengeSiteKey, setChallengeSiteKey] = useState(null);
57
+ const pendingMethodIdRef = useRef(null);
58
+ const pendingInputRef = useRef(void 0);
59
+ const challengeTimeoutRef = useRef(null);
60
+ useEffect(() => {
61
+ if (!autoHandleAuthCallback || handledCallbackRef.current) return;
62
+ handledCallbackRef.current = true;
63
+ void auth.handleAuthCallback().catch((callbackError) => {
64
+ setError(normalizeAuthError(toError(callbackError)));
65
+ });
66
+ }, [auth, autoHandleAuthCallback]);
67
+ useEffect(() => {
68
+ if (!auth.isAuthenticated) return;
69
+ setNotice(null);
70
+ setChallengeSiteKey(null);
71
+ pendingMethodIdRef.current = null;
72
+ pendingInputRef.current = void 0;
73
+ }, [auth.isAuthenticated]);
74
+ useEffect(() => {
75
+ if (challengeTimeoutRef.current) {
76
+ clearTimeout(challengeTimeoutRef.current);
77
+ challengeTimeoutRef.current = null;
78
+ }
79
+ if (!challengeSiteKey) return;
80
+ challengeTimeoutRef.current = setTimeout(() => {
81
+ setChallengeSiteKey(null);
82
+ pendingMethodIdRef.current = null;
83
+ pendingInputRef.current = void 0;
84
+ setError(new Error("Security check timed out. Please try again."));
85
+ setActiveMethodId(null);
86
+ }, 15e3);
87
+ return () => {
88
+ if (challengeTimeoutRef.current) {
89
+ clearTimeout(challengeTimeoutRef.current);
90
+ challengeTimeoutRef.current = null;
91
+ }
92
+ };
93
+ }, [challengeSiteKey]);
94
+ const availableMethods = useMemo(() => {
95
+ return getAvailableAuthMethods(methods);
96
+ }, [methods]);
97
+ const clearFeedback = useCallback(() => {
98
+ setError(null);
99
+ setNotice(null);
100
+ setChallengeSiteKey(null);
101
+ auth.clearError();
102
+ }, [auth]);
103
+ const startMethod = useCallback(
104
+ (methodId, input) => __async(null, null, function* () {
105
+ const method = methods.find((candidate) => candidate.id === methodId);
106
+ if (!method || !method.isAvailable) {
107
+ const unavailableError = new Error(`Auth method "${methodId}" is not available`);
108
+ setError(unavailableError);
109
+ throw unavailableError;
110
+ }
111
+ setError(null);
112
+ setNotice(null);
113
+ setActiveMethodId(methodId);
114
+ setSelectedMethodId(methodId);
115
+ try {
116
+ const result = yield method.start(
117
+ {
118
+ signIn: auth.signIn,
119
+ startAuth: auth.startAuth,
120
+ setSession: auth.setSession
121
+ },
122
+ input
123
+ );
124
+ if (result == null ? void 0 : result.notice) {
125
+ setNotice(result.notice);
126
+ }
127
+ return {};
128
+ } catch (startError) {
129
+ if (startError instanceof TurnstileChallengeError) {
130
+ pendingMethodIdRef.current = methodId;
131
+ pendingInputRef.current = input;
132
+ setChallengeSiteKey(startError.siteKey);
133
+ setActiveMethodId(null);
134
+ auth.clearError();
135
+ return { challengePending: true };
136
+ }
137
+ const resolvedError = normalizeAuthError(toError(startError));
138
+ setError(resolvedError);
139
+ throw resolvedError;
140
+ } finally {
141
+ setActiveMethodId(null);
142
+ }
143
+ }),
144
+ [auth, methods]
145
+ );
146
+ const handleTurnstileVerify = useCallback(
147
+ (token) => __async(null, null, function* () {
148
+ const methodId = pendingMethodIdRef.current;
149
+ const input = pendingInputRef.current;
150
+ if (!methodId) return;
151
+ setChallengeSiteKey(null);
152
+ pendingMethodIdRef.current = null;
153
+ pendingInputRef.current = void 0;
154
+ const method = methods.find((candidate) => candidate.id === methodId);
155
+ if (!method || !method.isAvailable) return;
156
+ setError(null);
157
+ setActiveMethodId(methodId);
158
+ try {
159
+ const result = yield method.start(
160
+ {
161
+ signIn: (options) => auth.signIn(__spreadProps(__spreadValues({}, options), { turnstileToken: token })),
162
+ startAuth: (options) => auth.startAuth(__spreadProps(__spreadValues({}, options), { turnstileToken: token })),
163
+ setSession: auth.setSession
164
+ },
165
+ input
166
+ );
167
+ if (result == null ? void 0 : result.notice) {
168
+ setNotice(result.notice);
169
+ }
170
+ } catch (retryError) {
171
+ setError(normalizeAuthError(toError(retryError)));
172
+ } finally {
173
+ setActiveMethodId(null);
174
+ }
175
+ }),
176
+ [auth, methods]
177
+ );
178
+ const handleTurnstileError = useCallback(() => {
179
+ setChallengeSiteKey(null);
180
+ pendingMethodIdRef.current = null;
181
+ pendingInputRef.current = void 0;
182
+ setError(new Error("Bot protection check failed. Please try again."));
183
+ setActiveMethodId(null);
184
+ }, []);
185
+ const signOut = useCallback(() => __async(null, null, function* () {
186
+ setError(null);
187
+ setNotice(null);
188
+ setChallengeSiteKey(null);
189
+ yield auth.signOut();
190
+ yield Promise.allSettled(
191
+ methods.map((method) => __async(null, null, function* () {
192
+ if (!method.disconnect) return;
193
+ yield method.disconnect();
194
+ }))
195
+ );
196
+ setSelectedMethodId(null);
197
+ }), [auth, methods]);
198
+ const value = useMemo(() => {
199
+ return {
200
+ activeMethodId,
201
+ availableMethods,
202
+ challengeSiteKey,
203
+ configuredMethods: methods,
204
+ error: error != null ? error : auth.error ? normalizeAuthError(auth.error) : null,
205
+ isBusy: auth.isLoading || activeMethodId !== null,
206
+ notice,
207
+ onChallengeError: handleTurnstileError,
208
+ onChallengeVerify: handleTurnstileVerify,
209
+ selectedMethodId,
210
+ startMethod,
211
+ clearFeedback,
212
+ signOut
213
+ };
214
+ }, [
215
+ activeMethodId,
216
+ auth.error,
217
+ auth.isLoading,
218
+ availableMethods,
219
+ challengeSiteKey,
220
+ clearFeedback,
221
+ error,
222
+ handleTurnstileError,
223
+ handleTurnstileVerify,
224
+ methods,
225
+ notice,
226
+ selectedMethodId,
227
+ signOut,
228
+ startMethod
229
+ ]);
230
+ return /* @__PURE__ */ jsx(AggAuthFlowContext.Provider, { value, children });
231
+ };
232
+ var useAggAuthFlow = () => {
233
+ const context = useContext(AggAuthFlowContext);
234
+ if (!context) {
235
+ throw new Error("useAggAuthFlow must be used within an <AggAuthProvider>");
236
+ }
237
+ return context;
238
+ };
239
+
240
+ // src/turnstile/index.tsx
241
+ import { Component } from "react";
242
+ import { Turnstile } from "@marsidev/react-turnstile";
243
+ import { jsx as jsx2 } from "react/jsx-runtime";
244
+ var TurnstileErrorBoundary = class extends Component {
245
+ constructor() {
246
+ super(...arguments);
247
+ this.state = { hasError: false };
248
+ }
249
+ static getDerivedStateFromError() {
250
+ return { hasError: true };
251
+ }
252
+ componentDidCatch(_error, _info) {
253
+ var _a, _b;
254
+ (_b = (_a = this.props).onError) == null ? void 0 : _b.call(_a);
255
+ }
256
+ render() {
257
+ if (this.state.hasError) return null;
258
+ return this.props.children;
259
+ }
260
+ };
261
+ var TurnstileWidget = ({
262
+ siteKey,
263
+ onVerify,
264
+ onError,
265
+ onExpire
266
+ }) => {
267
+ return /* @__PURE__ */ jsx2(TurnstileErrorBoundary, { onError, children: /* @__PURE__ */ jsx2(
268
+ Turnstile,
269
+ {
270
+ siteKey,
271
+ onSuccess: onVerify,
272
+ onError,
273
+ onExpire,
274
+ options: { appearance: "always", theme: "auto" }
275
+ }
276
+ ) });
277
+ };
278
+
279
+ // src/connect-button/connect-button.utils.ts
280
+ import { getWalletAddressFromUserProfile } from "@agg-build/hooks";
281
+ var getAuthProfileLabel = (user) => {
282
+ var _a, _b;
283
+ if (user == null ? void 0 : user.username) return user.username;
284
+ const walletAddress = getWalletAddressFromUserProfile(user);
285
+ if (walletAddress) return shortenAddress(walletAddress);
286
+ const providerAccountId = (_b = (_a = user == null ? void 0 : user.accounts) == null ? void 0 : _a[0]) == null ? void 0 : _b.providerAccountId;
287
+ if (providerAccountId) return shortenProfileLabel(providerAccountId);
288
+ if (user == null ? void 0 : user.id) return shortenProfileLabel(user.id);
289
+ return "";
290
+ };
291
+ var socialOrder = {
292
+ google: 0,
293
+ apple: 1,
294
+ twitter: 2
295
+ };
296
+ var walletOrder = {
297
+ siws: 0,
298
+ siwe: 1
299
+ };
300
+ var toViewMethod = (method) => {
301
+ return {
302
+ chain: method.chain,
303
+ description: method.description,
304
+ iconName: method.iconName,
305
+ id: method.id,
306
+ input: method.input,
307
+ isAvailable: method.isAvailable,
308
+ kind: method.kind,
309
+ label: method.label
310
+ };
311
+ };
312
+ var groupConnectButtonMethods = (methods) => {
313
+ var _a;
314
+ const emailMethod = (_a = methods.find((method) => method.kind === "email")) != null ? _a : null;
315
+ const socialMethods = methods.filter((method) => method.kind === "social").slice().sort((left, right) => {
316
+ var _a2, _b;
317
+ return ((_a2 = socialOrder[left.id]) != null ? _a2 : 99) - ((_b = socialOrder[right.id]) != null ? _b : 99);
318
+ }).map(toViewMethod);
319
+ const walletMethods = methods.filter((method) => method.kind === "wallet").slice().sort((left, right) => {
320
+ var _a2, _b;
321
+ return ((_a2 = walletOrder[left.id]) != null ? _a2 : 99) - ((_b = walletOrder[right.id]) != null ? _b : 99);
322
+ }).map(toViewMethod);
323
+ return {
324
+ emailMethod: emailMethod ? toViewMethod(emailMethod) : null,
325
+ socialMethods,
326
+ walletMethods
327
+ };
328
+ };
329
+
330
+ // src/connect-button/index.tsx
331
+ import { jsx as jsx3, jsxs } from "react/jsx-runtime";
332
+ var ConnectButton = ({
333
+ buttonProps,
334
+ classNames,
335
+ disabled,
336
+ onAuthMethodSelect,
337
+ onDepositClick,
338
+ onDisconnect,
339
+ onProfileCardClick,
340
+ onProfileClick,
341
+ onClaimWinningsClick,
342
+ claimReadyCount,
343
+ onWithdrawClick
344
+ }) => {
345
+ var _a, _b;
346
+ const [emailValue, setEmailValue] = useState2("");
347
+ const [emailError, setEmailError] = useState2(null);
348
+ const [isChooserOpen, setIsChooserOpen] = useState2(false);
349
+ const [isProfileMenuOpen, setIsProfileMenuOpen] = useState2(false);
350
+ const {
351
+ activeMethodId,
352
+ challengeSiteKey,
353
+ clearFeedback,
354
+ configuredMethods,
355
+ error,
356
+ isBusy,
357
+ notice,
358
+ onChallengeError,
359
+ onChallengeVerify,
360
+ signOut,
361
+ startMethod
362
+ } = useAggAuthFlow();
363
+ const { isAuthenticated, user } = useAggAuthContext2();
364
+ const {
365
+ totalBalance,
366
+ positionsBalanceTotal,
367
+ isLoading: isBalanceLoading,
368
+ error: balanceError
369
+ } = useAggBalanceState();
370
+ const { isDepositBlocked } = useGeoBlock();
371
+ const resolvedWalletAddress = (_a = getWalletAddressFromUserProfile2(user)) != null ? _a : "";
372
+ const resolvedAddressLabel = resolvedWalletAddress ? shortenAddress(resolvedWalletAddress) : void 0;
373
+ const resolvedProfileLabel = getAuthProfileLabel(user) || void 0;
374
+ const { emailMethod, socialMethods, walletMethods } = useMemo2(() => {
375
+ return groupConnectButtonMethods(configuredMethods);
376
+ }, [configuredMethods]);
377
+ useEffect2(() => {
378
+ if (!isAuthenticated) return;
379
+ setIsChooserOpen(false);
380
+ setEmailError(null);
381
+ }, [isAuthenticated]);
382
+ useEffect2(() => {
383
+ if (typeof window === "undefined") return;
384
+ const handleOpenChooserRequest = () => {
385
+ if (disabled || isAuthenticated) return;
386
+ setEmailError(null);
387
+ clearFeedback();
388
+ setIsChooserOpen(true);
389
+ };
390
+ window.addEventListener(AUTH_CHOOSER_OPEN_EVENT, handleOpenChooserRequest);
391
+ return () => {
392
+ window.removeEventListener(AUTH_CHOOSER_OPEN_EVENT, handleOpenChooserRequest);
393
+ };
394
+ }, [clearFeedback, disabled, isAuthenticated]);
395
+ const resolvedError = error != null ? error : balanceError;
396
+ const challengeContent = challengeSiteKey ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-3", children: [
397
+ /* @__PURE__ */ jsx3("p", { className: "text-agg-sm text-agg-muted-foreground text-center", children: "Please complete the verification below to continue." }),
398
+ /* @__PURE__ */ jsx3(
399
+ TurnstileWidget,
400
+ {
401
+ siteKey: challengeSiteKey,
402
+ onVerify: onChallengeVerify,
403
+ onError: onChallengeError,
404
+ onExpire: onChallengeError
405
+ }
406
+ )
407
+ ] }) : null;
408
+ const handleMethodSelection = (method) => __async(null, null, function* () {
409
+ if (!method.isAvailable || disabled || isBusy) return;
410
+ setEmailError(null);
411
+ clearFeedback();
412
+ setIsChooserOpen(false);
413
+ let result;
414
+ try {
415
+ result = yield startMethod(method.id);
416
+ } catch (e) {
417
+ setIsChooserOpen(true);
418
+ return;
419
+ }
420
+ if (result == null ? void 0 : result.challengePending) return;
421
+ yield Promise.resolve(onAuthMethodSelect == null ? void 0 : onAuthMethodSelect(method.id));
422
+ setIsChooserOpen(false);
423
+ });
424
+ const handleEmailSubmit = () => __async(null, null, function* () {
425
+ var _a2, _b2, _c;
426
+ if (!emailMethod || !emailMethod.isAvailable || disabled || isBusy) return;
427
+ const parsedEmail = parseEmail(emailValue);
428
+ if (!parsedEmail.success) {
429
+ setEmailError((_c = (_b2 = (_a2 = parsedEmail.error) == null ? void 0 : _a2.issues[0]) == null ? void 0 : _b2.message) != null ? _c : "Enter a valid email address.");
430
+ return;
431
+ }
432
+ setEmailError(null);
433
+ const result = yield startMethod(emailMethod.id, {
434
+ email: parsedEmail.data.email
435
+ });
436
+ if (result == null ? void 0 : result.challengePending) return;
437
+ yield Promise.resolve(onAuthMethodSelect == null ? void 0 : onAuthMethodSelect(emailMethod.id));
438
+ setEmailValue("");
439
+ setIsChooserOpen(false);
440
+ });
441
+ const handleDepositClick = () => {
442
+ if (disabled) return;
443
+ setIsProfileMenuOpen(false);
444
+ void Promise.resolve(onDepositClick == null ? void 0 : onDepositClick());
445
+ };
446
+ const handleProfileCardClick = () => {
447
+ if (disabled) return;
448
+ setIsProfileMenuOpen(false);
449
+ void Promise.resolve(onProfileCardClick == null ? void 0 : onProfileCardClick());
450
+ };
451
+ const handleProfileClick = () => {
452
+ if (disabled) return;
453
+ setIsProfileMenuOpen(false);
454
+ void Promise.resolve(onProfileClick == null ? void 0 : onProfileClick());
455
+ };
456
+ const handleClaimWinningsClick = () => {
457
+ if (disabled) return;
458
+ setIsProfileMenuOpen(false);
459
+ void Promise.resolve(onClaimWinningsClick == null ? void 0 : onClaimWinningsClick());
460
+ };
461
+ const handleWithdrawClick = () => {
462
+ if (disabled) return;
463
+ setIsProfileMenuOpen(false);
464
+ void Promise.resolve(onWithdrawClick == null ? void 0 : onWithdrawClick());
465
+ };
466
+ const handleDisconnectClick = () => __async(null, null, function* () {
467
+ if (disabled) return;
468
+ setIsProfileMenuOpen(false);
469
+ yield signOut();
470
+ yield Promise.resolve(onDisconnect == null ? void 0 : onDisconnect());
471
+ });
472
+ const handleChooserOpenChange = (open) => {
473
+ if (disabled) return;
474
+ setIsChooserOpen(open);
475
+ if (open) return;
476
+ setEmailError(null);
477
+ clearFeedback();
478
+ };
479
+ return /* @__PURE__ */ jsx3(
480
+ AuthConnectButtonView,
481
+ {
482
+ activeMethodId,
483
+ addressLabel: resolvedAddressLabel,
484
+ buttonProps,
485
+ challengeContent,
486
+ classNames,
487
+ disabled,
488
+ emailMethod,
489
+ emailError,
490
+ emailValue,
491
+ errorMessage: (_b = resolvedError == null ? void 0 : resolvedError.message) != null ? _b : null,
492
+ isAuthenticated,
493
+ isBalanceLoading,
494
+ isBusy,
495
+ isChooserOpen,
496
+ isProfileMenuOpen,
497
+ notice,
498
+ onChooserOpenChange: handleChooserOpenChange,
499
+ onDepositClick: handleDepositClick,
500
+ onDisconnectClick: () => {
501
+ void handleDisconnectClick();
502
+ },
503
+ onEmailChange: setEmailValue,
504
+ onEmailSubmit: () => {
505
+ void handleEmailSubmit();
506
+ },
507
+ onMethodSelect: (methodId) => {
508
+ const selectedMethod = [...socialMethods, ...walletMethods].find(
509
+ (method) => method.id === methodId
510
+ );
511
+ if (!selectedMethod) return;
512
+ void handleMethodSelection(selectedMethod);
513
+ },
514
+ onProfileCardClick: handleProfileCardClick,
515
+ onProfileClick: handleProfileClick,
516
+ onProfileMenuOpenChange: setIsProfileMenuOpen,
517
+ socialMethods,
518
+ onWithdrawClick: handleWithdrawClick,
519
+ profileLabel: resolvedProfileLabel,
520
+ totalBalance,
521
+ positionsBalance: positionsBalanceTotal,
522
+ claimReadyCount,
523
+ onClaimWinningsClick: handleClaimWinningsClick,
524
+ walletMethods,
525
+ isDepositBlocked
526
+ }
527
+ );
528
+ };
529
+ ConnectButton.displayName = "ConnectButton";
530
+
531
+ export {
532
+ AggAuthProvider,
533
+ useAggAuthFlow,
534
+ ConnectButton
535
+ };
@@ -0,0 +1,45 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ var __async = (__this, __arguments, generator) => {
21
+ return new Promise((resolve, reject) => {
22
+ var fulfilled = (value) => {
23
+ try {
24
+ step(generator.next(value));
25
+ } catch (e) {
26
+ reject(e);
27
+ }
28
+ };
29
+ var rejected = (value) => {
30
+ try {
31
+ step(generator.throw(value));
32
+ } catch (e) {
33
+ reject(e);
34
+ }
35
+ };
36
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
37
+ step((generator = generator.apply(__this, __arguments)).next());
38
+ });
39
+ };
40
+
41
+ export {
42
+ __spreadValues,
43
+ __spreadProps,
44
+ __async
45
+ };
@@ -0,0 +1,36 @@
1
+ // src/shared/utils.ts
2
+ var toError = (value) => {
3
+ return value instanceof Error ? value : new Error(String(value));
4
+ };
5
+ var normalizeAuthError = (error) => {
6
+ const lower = error.message.toLowerCase();
7
+ if (lower.includes("user rejected") || lower.includes("user denied") || lower.includes("rejected the request") || lower.includes("denied transaction signature")) {
8
+ return new Error("Wallet request rejected.");
9
+ }
10
+ return error;
11
+ };
12
+ var shortenAddress = (value) => {
13
+ if (value.length < 10) return value;
14
+ if (value.startsWith("0x")) return `${value.slice(0, 6)}...${value.slice(-4)}`;
15
+ return `${value.slice(0, 4)}...${value.slice(-4)}`;
16
+ };
17
+ var shortenProfileLabel = (value) => {
18
+ if (!value) return value;
19
+ if (value.includes("@")) return value;
20
+ if (value.startsWith("0x")) return shortenAddress(value);
21
+ if (value.length <= 16) return value;
22
+ return `${value.slice(0, 8)}...${value.slice(-5)}`;
23
+ };
24
+ var resolveRedirectUrl = (redirectUrl) => {
25
+ if (redirectUrl) return redirectUrl;
26
+ if (typeof window === "undefined") return "http://localhost";
27
+ return `${window.location.origin}${window.location.pathname}${window.location.search}`;
28
+ };
29
+
30
+ export {
31
+ toError,
32
+ normalizeAuthError,
33
+ shortenAddress,
34
+ shortenProfileLabel,
35
+ resolveRedirectUrl
36
+ };
@@ -0,0 +1,51 @@
1
+ import {
2
+ resolveRedirectUrl
3
+ } from "./chunk-BVV6GEOL.mjs";
4
+ import {
5
+ __async
6
+ } from "./chunk-AXBFBHS2.mjs";
7
+
8
+ // src/email/index.ts
9
+ import { parseEmailStrict, TurnstileChallengeError } from "@agg-build/hooks";
10
+ var createEmailAuthMethod = (options = {}) => {
11
+ var _a, _b, _c, _d, _e;
12
+ return {
13
+ id: "email",
14
+ kind: "email",
15
+ label: (_a = options.label) != null ? _a : "Email",
16
+ description: (_b = options.description) != null ? _b : "Get a magic link sent to your inbox.",
17
+ iconName: "email",
18
+ input: {
19
+ type: "email",
20
+ placeholder: (_c = options.placeholder) != null ? _c : "Email address",
21
+ submitLabel: (_d = options.submitLabel) != null ? _d : "Continue",
22
+ helperText: options.helperText
23
+ },
24
+ isAvailable: (_e = options.isAvailable) != null ? _e : true,
25
+ start: (_0, _1) => __async(null, [_0, _1], function* ({ startAuth }, input) {
26
+ var _a2, _b2;
27
+ const { email } = parseEmailStrict((_a2 = input == null ? void 0 : input.email) != null ? _a2 : "");
28
+ const response = yield startAuth({
29
+ provider: "email",
30
+ email,
31
+ redirectUrl: resolveRedirectUrl(options.redirectUrl)
32
+ });
33
+ if (response.type === "challenge_required") {
34
+ if (!response.siteKey) {
35
+ throw new Error("Server returned challenge_required but no siteKey was provided.");
36
+ }
37
+ throw new TurnstileChallengeError(response.siteKey);
38
+ }
39
+ if (response.type !== "magic_link") {
40
+ throw new Error(`AGG auth start returned an unexpected "${response.type}" response`);
41
+ }
42
+ return {
43
+ notice: (_b2 = options.successNotice) != null ? _b2 : "Check your email for a magic link to finish signing in."
44
+ };
45
+ })
46
+ };
47
+ };
48
+
49
+ export {
50
+ createEmailAuthMethod
51
+ };