@abstraxn/signer-react 2.2.1 → 2.2.3

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.
Files changed (32) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/src/components/AbstraxnProvider/AbstraxnProviderInner.js +31 -88
  3. package/dist/src/components/AbstraxnProvider/AbstraxnProviderInner.js.map +1 -1
  4. package/dist/src/components/AbstraxnProvider/useWalletInitialization.js +6 -3
  5. package/dist/src/components/AbstraxnProvider/useWalletInitialization.js.map +1 -1
  6. package/dist/src/components/AbstraxnProvider/utils.js +1 -12
  7. package/dist/src/components/AbstraxnProvider/utils.js.map +1 -1
  8. package/dist/src/components/OnboardingUI/OnboardingUIReact.js +13 -32
  9. package/dist/src/components/OnboardingUI/OnboardingUIReact.js.map +1 -1
  10. package/dist/src/components/OnboardingUI/OnboardingUIWeb.d.ts +1 -0
  11. package/dist/src/components/OnboardingUI/OnboardingUIWeb.js +31 -45
  12. package/dist/src/components/OnboardingUI/OnboardingUIWeb.js.map +1 -1
  13. package/dist/src/components/OnboardingUI/components/EmailForm.js +10 -1
  14. package/dist/src/components/OnboardingUI/components/EmailForm.js.map +1 -1
  15. package/dist/src/components/OnboardingUI/components/MfaForm.js +10 -3
  16. package/dist/src/components/OnboardingUI/components/MfaForm.js.map +1 -1
  17. package/dist/src/components/OnboardingUI/components/OtpForm.js +11 -4
  18. package/dist/src/components/OnboardingUI/components/OtpForm.js.map +1 -1
  19. package/dist/src/components/OnboardingUI/hooks/useAuthMethods.js +6 -3
  20. package/dist/src/components/OnboardingUI/hooks/useAuthMethods.js.map +1 -1
  21. package/dist/src/components/OnboardingUI/hooks/useOnboarding.js +2 -2
  22. package/dist/src/components/OnboardingUI/hooks/useOnboarding.js.map +1 -1
  23. package/dist/src/components/WalletModal/components/ManageWalletModal.js +105 -126
  24. package/dist/src/components/WalletModal/components/ManageWalletModal.js.map +1 -1
  25. package/dist/src/hooks.d.ts +59 -1
  26. package/dist/src/hooks.js +200 -0
  27. package/dist/src/hooks.js.map +1 -1
  28. package/dist/src/index.d.ts +1 -1
  29. package/dist/src/index.js +1 -1
  30. package/dist/src/index.js.map +1 -1
  31. package/dist/tsconfig.tsbuildinfo +1 -1
  32. package/package.json +2 -2
@@ -11,11 +11,15 @@ import { FiUsers, FiLink } from "react-icons/fi";
11
11
  import { TfiEmail } from "react-icons/tfi";
12
12
  import { BiShieldQuarter } from "react-icons/bi";
13
13
  import { useAbstraxnWallet } from "../../../AbstraxnProvider";
14
+ import { useEnableMfa } from "../../../hooks";
14
15
  import "./ManageWalletModal.css";
15
16
  import { QRCodeSVG } from "qrcode.react";
16
17
  function normalizeLinkedProvider(authProvider) {
17
18
  return authProvider === "otp" ? "email" : authProvider;
18
19
  }
20
+ function normalizeErrorMessage(message) {
21
+ return message.replace(/^network error:\s*/i, "");
22
+ }
19
23
  function AuthMethodIcon({ provider }) {
20
24
  const p = provider.toLowerCase();
21
25
  if (p === "google")
@@ -32,7 +36,7 @@ function AuthMethodIcon({ provider }) {
32
36
  }
33
37
  export function ManageWalletModal({ ...props }) {
34
38
  const { isOpen, onClose, isExternalWalletConnected, onExportPrivateKey, theme = "dark", userEmail, organizationName, } = props;
35
- const { getSupportedAuthMethods, getLinkedAuthMethods, linkAuthMethod, linkEmail, loginWithOTP, requestOtpForEmailLink, unlinkAuthMethod, whoami, getMfaStatus, enableMfa, verifySetupMfa, verifyMfa, disableMfaWithSignedPayload, } = useAbstraxnWallet();
39
+ const { getSupportedAuthMethods, getLinkedAuthMethods, linkAuthMethod, linkEmail, loginWithOTP, requestOtpForEmailLink, unlinkAuthMethod, whoami, getMfaStatus, verifyMfa, disableMfaWithSignedPayload, } = useAbstraxnWallet();
36
40
  const [showLinkedProfilesList, setShowLinkedProfilesList] = useState(false);
37
41
  const [supportedMethods, setSupportedMethods] = useState([]);
38
42
  const [linkedMethods, setLinkedMethods] = useState([]);
@@ -50,21 +54,13 @@ export function ManageWalletModal({ ...props }) {
50
54
  const [emailLinkResending, setEmailLinkResending] = useState(false);
51
55
  const [emailLinkResendCooldown, setEmailLinkResendCooldown] = useState(0);
52
56
  const emailLinkOtpInputsRef = useRef([]);
53
- // MFA state
54
57
  const [mfaStatus, setMfaStatus] = useState(null);
55
58
  const [mfaLoading, setMfaLoading] = useState(false);
56
- const [mfaError, setMfaError] = useState(null);
57
- // MFA setup flow state (QR + secret + TOTP + backup codes)
58
59
  const [showMfaSetupModal, setShowMfaSetupModal] = useState(false);
59
- const [mfaSetupStep, setMfaSetupStep] = useState("setup");
60
- const [mfaQrCode, setMfaQrCode] = useState(null);
61
- const [mfaSecret, setMfaSecret] = useState(null);
60
+ const [showMfaBackupModal, setShowMfaBackupModal] = useState(false);
62
61
  const [mfaSetupCode, setMfaSetupCode] = useState("");
63
62
  const [mfaRecoveryCode, setMfaRecoveryCode] = useState("");
64
- const [mfaSetupLoading, setMfaSetupLoading] = useState(false);
65
- const [mfaSetupError, setMfaSetupError] = useState(null);
66
- const [mfaBackupCodes, setMfaBackupCodes] = useState([]);
67
- const [showMfaBackupModal, setShowMfaBackupModal] = useState(false);
63
+ const { canEnableMfaFlow, setupState, isLoading: mfaSetupLoading, error: mfaSetupError, start, goToSetup, goToVerify, goToRecovery, verifyCode, verifyRecoveryCode, reset, } = useEnableMfa();
68
64
  const [mfaSecretCopied, setMfaSecretCopied] = useState(false);
69
65
  const [mfaBackupCodesCopied, setMfaBackupCodesCopied] = useState(false);
70
66
  const mfaSetupVerifyButtonRef = useRef(null);
@@ -78,6 +74,10 @@ export function ManageWalletModal({ ...props }) {
78
74
  const [mfaDisableLoading, setMfaDisableLoading] = useState(false);
79
75
  const [mfaDisableError, setMfaDisableError] = useState(null);
80
76
  const mfaDisableVerifyButtonRef = useRef(null);
77
+ const hasFetchedMfaForOpenRef = useRef(false);
78
+ const hasFetchedLinkedProfilesForOpenRef = useRef(false);
79
+ const linkedProfilesFetchPromiseRef = useRef(null);
80
+ const mfaStatusRequestInFlightRef = useRef(false);
81
81
  const showFeedback = useCallback((message, type = "success") => {
82
82
  if (type === "error") {
83
83
  setLinkUnlinkError(message);
@@ -88,35 +88,48 @@ export function ManageWalletModal({ ...props }) {
88
88
  const fetchLinkedProfilesData = useCallback(async () => {
89
89
  if (!getSupportedAuthMethods || !getLinkedAuthMethods || isExternalWalletConnected)
90
90
  return;
91
- setLinkedLoading(true);
92
- setLinkedError(null);
93
- try {
94
- const [supportedRes, linkedRes] = await Promise.all([
95
- getSupportedAuthMethods(),
96
- getLinkedAuthMethods(),
97
- ]);
98
- const loginProvider = whoami?.loginProvider?.toLowerCase();
99
- const supported = supportedRes.supportedMethods ?? [];
100
- const filteredSupported = loginProvider != null && loginProvider !== ""
101
- ? supported.filter((method) => method.provider.toLowerCase() !== loginProvider)
102
- : supported;
103
- setSupportedMethods(filteredSupported);
104
- setLinkedMethods(linkedRes.linkedMethods ?? []);
105
- }
106
- catch (err) {
107
- const msg = err instanceof Error ? err.message : "Failed to load auth methods";
108
- setLinkedError(msg);
109
- setSupportedMethods([]);
110
- setLinkedMethods([]);
111
- }
112
- finally {
113
- setLinkedLoading(false);
91
+ if (linkedProfilesFetchPromiseRef.current) {
92
+ await linkedProfilesFetchPromiseRef.current;
93
+ return;
114
94
  }
95
+ const fetchPromise = (async () => {
96
+ setLinkedLoading(true);
97
+ setLinkedError(null);
98
+ try {
99
+ const [supportedRes, linkedRes] = await Promise.all([
100
+ getSupportedAuthMethods(),
101
+ getLinkedAuthMethods(),
102
+ ]);
103
+ const loginProvider = whoami?.loginProvider?.toLowerCase();
104
+ const supported = supportedRes.supportedMethods ?? [];
105
+ const filteredSupported = loginProvider != null && loginProvider !== ""
106
+ ? supported.filter((method) => method.provider.toLowerCase() !== loginProvider)
107
+ : supported;
108
+ setSupportedMethods(filteredSupported);
109
+ setLinkedMethods(linkedRes.linkedMethods ?? []);
110
+ }
111
+ catch (err) {
112
+ const msg = err instanceof Error ? normalizeErrorMessage(err.message) : "Failed to load auth methods";
113
+ setLinkedError(msg);
114
+ setSupportedMethods([]);
115
+ setLinkedMethods([]);
116
+ }
117
+ finally {
118
+ setLinkedLoading(false);
119
+ }
120
+ })();
121
+ linkedProfilesFetchPromiseRef.current = fetchPromise;
122
+ await fetchPromise.finally(() => {
123
+ linkedProfilesFetchPromiseRef.current = null;
124
+ });
115
125
  }, [getSupportedAuthMethods, getLinkedAuthMethods, isExternalWalletConnected, whoami]);
116
126
  const handleOpenLinkedProfiles = useCallback(() => {
117
127
  setShowLinkedProfilesList(true);
118
- fetchLinkedProfilesData();
119
- }, [fetchLinkedProfilesData]);
128
+ const hasLinkedProfilesData = supportedMethods.length > 0 || linkedMethods.length > 0;
129
+ if (!hasLinkedProfilesData && !linkedLoading) {
130
+ fetchLinkedProfilesData();
131
+ }
132
+ }, [fetchLinkedProfilesData, linkedLoading, linkedMethods.length, supportedMethods.length]);
120
133
  const isProviderLinked = useCallback((provider) => {
121
134
  return linkedMethods.some((m) => normalizeLinkedProvider(m.authProvider) === provider.toLowerCase());
122
135
  }, [linkedMethods]);
@@ -141,7 +154,7 @@ export function ManageWalletModal({ ...props }) {
141
154
  await fetchLinkedProfilesData();
142
155
  }
143
156
  catch (err) {
144
- const msg = err instanceof Error ? err.message : "Failed to connect";
157
+ const msg = err instanceof Error ? normalizeErrorMessage(err.message) : "Failed to connect";
145
158
  setLinkUnlinkError(msg);
146
159
  }
147
160
  finally {
@@ -165,7 +178,7 @@ export function ManageWalletModal({ ...props }) {
165
178
  showFeedback("Check your email for the code", "success");
166
179
  }
167
180
  catch (err) {
168
- const msg = err instanceof Error ? err.message : "Failed to send OTP";
181
+ const msg = err instanceof Error ? normalizeErrorMessage(err.message) : "Failed to send OTP";
169
182
  setEmailLinkError(msg);
170
183
  showFeedback(msg, "error");
171
184
  }
@@ -189,7 +202,7 @@ export function ManageWalletModal({ ...props }) {
189
202
  showFeedback("Code resent", "success");
190
203
  }
191
204
  catch (err) {
192
- const msg = err instanceof Error ? err.message : "Failed to resend";
205
+ const msg = err instanceof Error ? normalizeErrorMessage(err.message) : "Failed to resend";
193
206
  setEmailLinkError(msg);
194
207
  showFeedback(msg, "error");
195
208
  }
@@ -214,7 +227,7 @@ export function ManageWalletModal({ ...props }) {
214
227
  await fetchLinkedProfilesData();
215
228
  }
216
229
  catch (err) {
217
- const msg = err instanceof Error ? err.message : "Failed to link email";
230
+ const msg = err instanceof Error ? normalizeErrorMessage(err.message) : "Failed to link email";
218
231
  setEmailLinkError(msg);
219
232
  showFeedback(msg, "error");
220
233
  }
@@ -277,33 +290,34 @@ export function ManageWalletModal({ ...props }) {
277
290
  handleLinkEmailSubmit();
278
291
  }
279
292
  }, [emailLinkOtpCode, actionProvider, emailLinkResending, emailLinkError, handleLinkEmailSubmit]);
293
+ const mfaSetupStep = setupState?.step === "complete" || !setupState ? "setup" : setupState.step;
294
+ const mfaQrCode = setupState?.step === "setup" ? setupState.qrCode : null;
295
+ const mfaSecret = setupState?.step === "setup" ? setupState.secret : null;
296
+ const mfaBackupCodes = setupState?.step === "complete" ? setupState.backupCodes : [];
280
297
  const refreshMfaStatus = useCallback(async () => {
281
- if (!getMfaStatus)
298
+ if (!getMfaStatus || mfaStatusRequestInFlightRef.current)
282
299
  return;
300
+ mfaStatusRequestInFlightRef.current = true;
283
301
  setMfaLoading(true);
284
- setMfaError(null);
285
302
  try {
286
303
  const status = await getMfaStatus();
287
304
  setMfaStatus(status);
288
305
  }
289
- catch (err) {
290
- const msg = err instanceof Error ? err.message : "Failed to load MFA status";
291
- setMfaError(msg);
306
+ catch {
307
+ setMfaStatus(null);
292
308
  }
293
309
  finally {
294
310
  setMfaLoading(false);
311
+ mfaStatusRequestInFlightRef.current = false;
295
312
  }
296
313
  }, [getMfaStatus]);
297
314
  const resetMfaSetupState = useCallback(() => {
298
- setMfaSetupStep("setup");
299
- setMfaQrCode(null);
300
- setMfaSecret(null);
301
315
  setMfaSetupCode("");
302
316
  setMfaRecoveryCode("");
303
- setMfaSetupError(null);
304
- setMfaSetupLoading(false);
305
- setMfaBackupCodes([]);
306
- }, []);
317
+ setShowMfaSetupModal(false);
318
+ setShowMfaBackupModal(false);
319
+ reset();
320
+ }, [reset]);
307
321
  const resetMfaDisableState = useCallback(() => {
308
322
  setShowMfaDisableAuthModal(false);
309
323
  setShowMfaDisableConfirmModal(false);
@@ -325,7 +339,7 @@ export function ManageWalletModal({ ...props }) {
325
339
  setMfaDisableCode("");
326
340
  }
327
341
  catch (err) {
328
- setMfaDisableError(err instanceof Error ? err.message : "Invalid authentication code");
342
+ setMfaDisableError(err instanceof Error ? normalizeErrorMessage(err.message) : "Invalid authentication code");
329
343
  }
330
344
  finally {
331
345
  setMfaDisableLoading(false);
@@ -348,7 +362,7 @@ export function ManageWalletModal({ ...props }) {
348
362
  setMfaDisableRecoveryCode("");
349
363
  }
350
364
  catch (err) {
351
- setMfaDisableError(err instanceof Error ? err.message : "Invalid backup code");
365
+ setMfaDisableError(err instanceof Error ? normalizeErrorMessage(err.message) : "Invalid backup code");
352
366
  }
353
367
  finally {
354
368
  setMfaDisableLoading(false);
@@ -377,7 +391,7 @@ export function ManageWalletModal({ ...props }) {
377
391
  showFeedback("2FA disabled successfully", "success");
378
392
  }
379
393
  catch (err) {
380
- const msg = err instanceof Error ? err.message : "Failed to disable 2FA";
394
+ const msg = err instanceof Error ? normalizeErrorMessage(err.message) : "Failed to disable 2FA";
381
395
  setMfaDisableError(msg);
382
396
  }
383
397
  finally {
@@ -385,74 +399,27 @@ export function ManageWalletModal({ ...props }) {
385
399
  }
386
400
  }, [disableMfaWithSignedPayload, refreshMfaStatus, resetMfaDisableState, showFeedback]);
387
401
  const startMfaSetup = useCallback(async () => {
388
- if (!enableMfa)
389
- return;
390
- resetMfaSetupState();
391
- setShowMfaSetupModal(true);
392
- setMfaSetupLoading(true);
393
- try {
394
- const result = await enableMfa();
395
- setMfaQrCode(result.qrCode);
396
- setMfaSecret(result.secret);
402
+ const result = await start();
403
+ if (result) {
404
+ setShowMfaSetupModal(true);
397
405
  }
398
- catch (err) {
399
- const msg = err instanceof Error ? err.message : "Failed to enable MFA";
400
- setMfaSetupError(msg);
401
- setShowMfaSetupModal(false);
402
- }
403
- finally {
404
- setMfaSetupLoading(false);
405
- }
406
- }, [enableMfa, resetMfaSetupState]);
406
+ }, [start]);
407
407
  const handleVerifyMfaSetup = useCallback(async () => {
408
- if (!verifySetupMfa)
409
- return;
410
- const trimmed = mfaSetupCode.trim();
411
- if (trimmed.length !== 6) {
412
- setMfaSetupError("Please enter a 6-digit code");
413
- return;
414
- }
415
- setMfaSetupLoading(true);
416
- setMfaSetupError(null);
417
- try {
418
- const result = await verifySetupMfa(trimmed);
419
- setMfaBackupCodes(result.backupCodes || []);
408
+ const result = await verifyCode(mfaSetupCode);
409
+ if (result) {
420
410
  setShowMfaSetupModal(false);
421
411
  setShowMfaBackupModal(true);
422
- await refreshMfaStatus();
412
+ setMfaSetupCode("");
423
413
  showFeedback("MFA enabled successfully.", "success");
414
+ await refreshMfaStatus();
424
415
  }
425
- catch (err) {
426
- const msg = err instanceof Error ? err.message : "Invalid TOTP code";
427
- setMfaSetupError(msg);
428
- }
429
- finally {
430
- setMfaSetupLoading(false);
431
- }
432
- }, [verifySetupMfa, mfaSetupCode, refreshMfaStatus, showFeedback]);
416
+ }, [verifyCode, mfaSetupCode, showFeedback, refreshMfaStatus]);
433
417
  const handleVerifyRecoveryCode = useCallback(async () => {
434
- if (!verifyMfa)
435
- return;
436
- const trimmed = mfaRecoveryCode.trim().toUpperCase();
437
- if (!/^[A-Z0-9]{8}$/.test(trimmed)) {
438
- setMfaSetupError("Please enter a valid 8-character recovery code");
439
- return;
440
- }
441
- setMfaSetupLoading(true);
442
- setMfaSetupError(null);
443
- try {
444
- await verifyMfa(trimmed);
445
- setMfaSetupStep("verify");
418
+ const ok = await verifyRecoveryCode(mfaRecoveryCode);
419
+ if (ok) {
446
420
  setMfaRecoveryCode("");
447
421
  }
448
- catch (err) {
449
- const msg = err instanceof Error ? err.message : "Invalid recovery code";
450
- setMfaSetupError(msg);
451
- }
452
- finally {
453
- setMfaSetupLoading(false);
454
- }
455
- }, [verifyMfa, mfaRecoveryCode]);
422
+ }, [verifyRecoveryCode, mfaRecoveryCode]);
456
423
  const handleCopyMfaSecret = useCallback(() => {
457
424
  if (!mfaSecret)
458
425
  return;
@@ -518,7 +485,7 @@ export function ManageWalletModal({ ...props }) {
518
485
  await fetchLinkedProfilesData();
519
486
  }
520
487
  catch (err) {
521
- showFeedback(err instanceof Error ? err.message : "Failed to disconnect", "error");
488
+ showFeedback(err instanceof Error ? normalizeErrorMessage(err.message) : "Failed to disconnect", "error");
522
489
  }
523
490
  finally {
524
491
  setActionProvider(null);
@@ -539,8 +506,23 @@ export function ManageWalletModal({ ...props }) {
539
506
  return () => clearInterval(id);
540
507
  }, [emailLinkStep, emailLinkResendCooldown]);
541
508
  useEffect(() => {
542
- if (!isOpen || isExternalWalletConnected)
509
+ if (!isOpen || isExternalWalletConnected) {
510
+ hasFetchedLinkedProfilesForOpenRef.current = false;
511
+ return;
512
+ }
513
+ if (hasFetchedLinkedProfilesForOpenRef.current)
514
+ return;
515
+ hasFetchedLinkedProfilesForOpenRef.current = true;
516
+ fetchLinkedProfilesData();
517
+ }, [isOpen, isExternalWalletConnected, fetchLinkedProfilesData]);
518
+ useEffect(() => {
519
+ if (!isOpen || isExternalWalletConnected) {
520
+ hasFetchedMfaForOpenRef.current = false;
521
+ return;
522
+ }
523
+ if (hasFetchedMfaForOpenRef.current)
543
524
  return;
525
+ hasFetchedMfaForOpenRef.current = true;
544
526
  refreshMfaStatus();
545
527
  }, [isOpen, isExternalWalletConnected, refreshMfaStatus]);
546
528
  useEffect(() => {
@@ -556,10 +538,9 @@ export function ManageWalletModal({ ...props }) {
556
538
  resetMfaSetupState();
557
539
  }, children: _jsxs("div", { className: `wallet-modal-content wallet-modal-theme-${theme} wallet-modal-manage mfa-redesign-container`, onClick: (e) => e.stopPropagation(), children: [_jsxs("div", { className: "wallet-modal-receive-header", children: [_jsx("button", { className: "wallet-modal-back", onClick: () => {
558
540
  if (mfaSetupStep === "verify" || mfaSetupStep === "recovery") {
559
- setMfaSetupStep("setup");
541
+ goToSetup();
560
542
  setMfaSetupCode("");
561
543
  setMfaRecoveryCode("");
562
- setMfaSetupError(null);
563
544
  return;
564
545
  }
565
546
  setShowMfaSetupModal(false);
@@ -569,10 +550,9 @@ export function ManageWalletModal({ ...props }) {
569
550
  const label = userEmail ? `${issuer}:${userEmail}` : issuer;
570
551
  return `otpauth://totp/${encodeURIComponent(label)}?secret=${mfaSecret}&issuer=${encodeURIComponent(issuer)}`;
571
552
  })(), size: 160, level: "L", includeMargin: false }) })) : (_jsx("div", { className: "mfa-qr-placeholder", children: mfaSetupLoading ? "Generating QR..." : "QR Code" })), mfaSecret && (_jsxs("div", { className: "mfa-secret-display", children: [_jsx(IoKeyOutline, { size: 16, className: "mfa-secret-key-icon" }), _jsx("code", { className: "mfa-secret-code", children: mfaSecret }), _jsx("button", { type: "button", className: `mfa-secret-copy ${mfaSecretCopied ? "copied" : ""}`, onClick: handleCopyMfaSecret, children: mfaSecretCopied ? _jsx(IoCheckmarkOutline, { size: 18 }) : _jsx(IoCopyOutline, { size: 18 }) })] }))] }), _jsx("button", { type: "button", className: "mfa-verify-button", onClick: () => {
572
- setMfaSetupStep("verify");
553
+ goToVerify();
573
554
  setMfaSetupCode("");
574
555
  setMfaRecoveryCode("");
575
- setMfaSetupError(null);
576
556
  }, disabled: mfaSetupLoading || !mfaSecret, children: "Continue" })] })) : mfaSetupStep === "verify" ? (_jsxs("div", { className: "mfa-verification-section", children: [_jsx("div", { className: "mfa-divider", children: _jsx("span", { children: "Enter 6-digit verification code" }) }), mfaSetupError && (_jsx("p", { className: "mfa-setup-error", style: { marginBottom: 12 }, children: mfaSetupError })), _jsx("div", { className: "mfa-otp-grid", children: [0, 1, 2, 3, 4, 5].map((index) => (_jsx("div", { className: "mfa-otp-slot", children: _jsx("input", { type: "text", inputMode: "numeric", maxLength: 1, value: mfaSetupCode[index] || "", onChange: (e) => {
577
557
  const val = e.target.value.replace(/\D/g, "");
578
558
  if (val) {
@@ -608,8 +588,7 @@ export function ManageWalletModal({ ...props }) {
608
588
  }
609
589
  }
610
590
  }, className: "mfa-otp-input" }) }, index))) }), _jsx("p", { className: "mfa-refresh-text", children: "Code refreshes every 30 seconds" }), _jsx("button", { ref: mfaSetupVerifyButtonRef, type: "button", className: "mfa-verify-button", onClick: handleVerifyMfaSetup, disabled: mfaSetupLoading || mfaSetupCode.length !== 6, children: mfaSetupLoading ? "Verifying..." : "Verify & continue" }), _jsxs("p", { className: "mfa-trouble-text", children: ["Having trouble?", " ", _jsx("button", { type: "button", className: "mfa-link-button", onClick: () => {
611
- setMfaSetupStep("recovery");
612
- setMfaSetupError(null);
591
+ goToRecovery();
613
592
  setMfaRecoveryCode("");
614
593
  }, children: "Use a recovery code" })] })] })) : (_jsxs("div", { className: "mfa-recovery-section", children: [_jsx("div", { className: "mfa-divider", children: _jsx("span", { children: "Enter 8 charater backup code" }) }), mfaSetupError && (_jsx("p", { className: "mfa-setup-error", style: { marginBottom: 12 }, children: mfaSetupError })), _jsx("input", { type: "text", inputMode: "text", maxLength: 8, value: mfaRecoveryCode, onChange: (e) => {
615
594
  const val = e.target.value.toUpperCase().replace(/[^A-Z0-9]/g, "").slice(0, 8);
@@ -619,13 +598,13 @@ export function ManageWalletModal({ ...props }) {
619
598
  if (showMfaBackupModal) {
620
599
  return (_jsx("div", { className: `wallet-modal-overlay wallet-modal-theme-${theme}`, onClick: () => {
621
600
  setShowMfaBackupModal(false);
622
- setMfaBackupCodes([]);
601
+ reset();
623
602
  }, children: _jsxs("div", { className: `wallet-modal-content wallet-modal-theme-${theme} wallet-modal-manage mfa-redesign-container`, onClick: (e) => e.stopPropagation(), children: [_jsxs("div", { className: "wallet-modal-receive-header", children: [_jsx("button", { className: "wallet-modal-back", onClick: () => {
624
603
  setShowMfaBackupModal(false);
625
- setMfaBackupCodes([]);
604
+ reset();
626
605
  }, "aria-label": "Back", children: _jsx(IoChevronBack, { size: 20 }) }), _jsx("h2", { className: "wallet-modal-receive-title", children: "Backup Codes" }), _jsx("button", { className: "wallet-modal-close", onClick: onClose, "aria-label": "Close", children: _jsx(IoClose, { size: 24 }) })] }), _jsxs("div", { className: "mfa-redesign-content", children: [_jsxs("div", { className: "mfa-info-box", children: [_jsx("div", { className: "mfa-info-icon", children: _jsx(IoKeyOutline, { size: 20 }) }), _jsx("p", { className: "mfa-info-text", children: "Backup codes can be used to access your account if you lose access to your primary authentication method. Store them securely as these codes will not be shown again." })] }), _jsx("div", { className: "wallet-modal-mfa-backup-heading", children: _jsx("span", { className: "wallet-modal-mfa-backup-heading-label", children: "Recovery Codes" }) }), _jsx("div", { className: "wallet-modal-mfa-backup-list", children: mfaBackupCodes.map((code, index) => (_jsx("div", { className: "wallet-modal-mfa-backup-code-wrapper", children: _jsx("code", { className: "wallet-modal-mfa-backup-code", children: code }) }, index))) }), _jsxs("div", { className: "wallet-modal-mfa-backup-actions", children: [_jsxs("button", { type: "button", className: `wallet-modal-mfa-backup-action-btn ${mfaBackupCodesCopied ? 'copied' : ''}`, onClick: handleCopyBackupCodes, disabled: !mfaBackupCodes.length, children: [mfaBackupCodesCopied ? _jsx(IoCheckmarkOutline, { size: 18 }) : _jsx(IoCopyOutline, { size: 18 }), mfaBackupCodesCopied ? "Copied" : "Copy All"] }), _jsxs("button", { type: "button", className: "wallet-modal-mfa-backup-action-btn", onClick: handleDownloadBackupCodes, disabled: !mfaBackupCodes.length, children: [_jsx(IoCloudDownloadOutline, { size: 18 }), "Download"] })] }), _jsx("button", { type: "button", className: "mfa-verify-button", onClick: () => {
627
606
  setShowMfaBackupModal(false);
628
- setMfaBackupCodes([]);
607
+ reset();
629
608
  }, children: "I've saved these codes" })] })] }) }));
630
609
  }
631
610
  if (showMfaDisableAuthModal) {
@@ -720,7 +699,7 @@ export function ManageWalletModal({ ...props }) {
720
699
  return (_jsx("div", { className: `wallet-modal-overlay wallet-modal-theme-${theme}`, onClick: onClose, children: _jsxs("div", { className: `wallet-modal-content wallet-modal-theme-${theme} wallet-modal-manage`, onClick: (e) => e.stopPropagation(), children: [_jsxs("div", { className: "wallet-modal-receive-header", children: [_jsx("button", { className: "wallet-modal-back", onClick: onClose, "aria-label": "Back", children: _jsx(IoChevronBack, { size: 20 }) }), _jsx("h2", { className: "wallet-modal-receive-title", children: "Manage Wallet" }), _jsx("button", { className: "wallet-modal-close", onClick: onClose, "aria-label": "Close", children: _jsx(IoClose, { size: 24 }) })] }), _jsx("div", { className: "wallet-modal-manage-content", children: _jsxs("div", { className: "wallet-modal-manage-list", children: [!isExternalWalletConnected && (_jsxs("button", { className: "wallet-modal-manage-list-item", onClick: handleOpenLinkedProfiles, type: "button", children: [_jsx("div", { className: "wallet-modal-manage-list-icon", "aria-hidden": "true", children: _jsx(FiUsers, { size: 20 }) }), _jsx("span", { className: "wallet-modal-manage-list-label", children: "Auth Methods" }), _jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", className: "wallet-modal-manage-list-arrow", "aria-hidden": "true", children: _jsx("path", { d: "M6 12L10 8L6 4", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })] })), !isExternalWalletConnected && (_jsxs("button", { className: "wallet-modal-manage-list-item", onClick: () => {
721
700
  if (mfaLoading)
722
701
  return;
723
- if (!getMfaStatus || !enableMfa || !verifySetupMfa) {
702
+ if (!canEnableMfaFlow) {
724
703
  return;
725
704
  }
726
705
  if (mfaStatus?.enabled) {