@retinalabsllc/zairusjs 11.0.1 → 11.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -71,10 +71,15 @@ interface PipleAuthProps {
71
71
  }) => Promise<{
72
72
  success: boolean;
73
73
  error?: string;
74
+ has2FA?: boolean;
75
+ hasPasskey?: boolean;
76
+ passkeyOptions?: any;
74
77
  }>;
75
78
  onVerifyOtp: (payload: {
76
79
  email: string;
77
- code: string;
80
+ code?: string;
81
+ isPasskey?: boolean;
82
+ passkeyCredential?: any;
78
83
  }) => Promise<{
79
84
  success: boolean;
80
85
  error?: string;
package/dist/index.d.ts CHANGED
@@ -71,10 +71,15 @@ interface PipleAuthProps {
71
71
  }) => Promise<{
72
72
  success: boolean;
73
73
  error?: string;
74
+ has2FA?: boolean;
75
+ hasPasskey?: boolean;
76
+ passkeyOptions?: any;
74
77
  }>;
75
78
  onVerifyOtp: (payload: {
76
79
  email: string;
77
- code: string;
80
+ code?: string;
81
+ isPasskey?: boolean;
82
+ passkeyCredential?: any;
78
83
  }) => Promise<{
79
84
  success: boolean;
80
85
  error?: string;
package/dist/index.js CHANGED
@@ -369,6 +369,7 @@ var import_react6 = __toESM(require("react"));
369
369
  var import_navigation2 = require("next/navigation");
370
370
  var import_react_hot_toast = __toESM(require("react-hot-toast"));
371
371
  var import_react_google_recaptcha_v3 = require("react-google-recaptcha-v3");
372
+ var import_browser = require("@simplewebauthn/browser");
372
373
  var InputSpinner = () => /* @__PURE__ */ import_react6.default.createElement("svg", { className: "animate-spin h-4 w-4 text-neutral-400", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24" }, /* @__PURE__ */ import_react6.default.createElement("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), /* @__PURE__ */ import_react6.default.createElement("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" }));
373
374
  function AuthFormInner({
374
375
  companyName,
@@ -400,6 +401,9 @@ function AuthFormInner({
400
401
  const [lastName, setLastName] = (0, import_react6.useState)("");
401
402
  const [orgName, setOrgName] = (0, import_react6.useState)("");
402
403
  const [agreedToTerms, setAgreedToTerms] = (0, import_react6.useState)(false);
404
+ const [userHas2FA, setUserHas2FA] = (0, import_react6.useState)(false);
405
+ const [userHasPasskey, setUserHasPasskey] = (0, import_react6.useState)(false);
406
+ const [authOptions, setAuthOptions] = (0, import_react6.useState)(null);
403
407
  const [otp, setOtp] = (0, import_react6.useState)(["", "", "", "", "", ""]);
404
408
  const inputRefs = (0, import_react6.useRef)([]);
405
409
  const cleanAlpha = (val) => val.replace(/[^a-zA-Z\s-]/g, "");
@@ -417,9 +421,7 @@ function AuthFormInner({
417
421
  const newOtp = [...otp];
418
422
  newOtp[index] = cleanValue.slice(-1);
419
423
  setOtp(newOtp);
420
- if (cleanValue && index < 5) {
421
- inputRefs.current[index + 1]?.focus();
422
- }
424
+ if (cleanValue && index < 5) inputRefs.current[index + 1]?.focus();
423
425
  };
424
426
  const handlePaste = (e) => {
425
427
  e.preventDefault();
@@ -428,13 +430,10 @@ function AuthFormInner({
428
430
  if (!numbersOnly) return;
429
431
  const newOtp = [...otp];
430
432
  const length = Math.min(numbersOnly.length, 6);
431
- for (let i = 0; i < length; i++) {
432
- newOtp[i] = numbersOnly[i];
433
- }
433
+ for (let i = 0; i < length; i++) newOtp[i] = numbersOnly[i];
434
434
  setOtp(newOtp);
435
- if (length < 6) {
436
- inputRefs.current[length]?.focus();
437
- } else {
435
+ if (length < 6) inputRefs.current[length]?.focus();
436
+ else {
438
437
  inputRefs.current[5]?.focus();
439
438
  verifyOtpCode(newOtp.join(""));
440
439
  }
@@ -461,7 +460,10 @@ function AuthFormInner({
461
460
  recaptchaToken
462
461
  });
463
462
  if (res.success) {
464
- import_react_hot_toast.default.success("Verification code sent");
463
+ setUserHas2FA(!!res.has2FA);
464
+ setUserHasPasskey(!!res.hasPasskey);
465
+ if (res.passkeyOptions) setAuthOptions(res.passkeyOptions);
466
+ import_react_hot_toast.default.success(res.has2FA ? "Security check required" : "Verification code sent");
465
467
  setStep("OTP");
466
468
  setCountdown(60);
467
469
  } else {
@@ -491,6 +493,23 @@ function AuthFormInner({
491
493
  setIsSubmitting(false);
492
494
  }
493
495
  };
496
+ const triggerPasskeyLogin = async () => {
497
+ if (!authOptions || isSubmitting) return;
498
+ setIsSubmitting(true);
499
+ try {
500
+ const credentialResponse = await (0, import_browser.startAuthentication)({ optionsJSON: authOptions });
501
+ const res = await onVerifyOtp({ email: emailId, isPasskey: true, passkeyCredential: credentialResponse });
502
+ if (res.success) {
503
+ window.location.href = res.redirect || redirectUrl;
504
+ } else {
505
+ import_react_hot_toast.default.error(res.error || "Device verification failed.");
506
+ }
507
+ } catch (err) {
508
+ if (err.name !== "NotAllowedError") import_react_hot_toast.default.error("Passkey verification interrupted.");
509
+ } finally {
510
+ setIsSubmitting(false);
511
+ }
512
+ };
494
513
  const handleNextSignupStep = () => {
495
514
  if (signupStep === "NAME") {
496
515
  if (requireOrganization) setSignupStep("ORGANIZATION");
@@ -509,7 +528,7 @@ function AuthFormInner({
509
528
  }
510
529
  return false;
511
530
  };
512
- return /* @__PURE__ */ import_react6.default.createElement("div", { className: "w-full max-w-md mx-auto flex flex-col items-center gap-4 relative z-10 animate-in fade-in duration-300" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "w-full bg-white rounded-2xl overflow-hidden" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "p-8 md:p-12" }, step === "INPUT" && /* @__PURE__ */ import_react6.default.createElement("div", { className: "animate-in fade-in duration-300" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "mb-12 text-center mt-2" }, /* @__PURE__ */ import_react6.default.createElement("h2", { className: " text-xl text-black mb-2 tracking-tight " }, mode === "LOGIN" ? `${companyName} ${workspaceLabel}` : "Create Account"), /* @__PURE__ */ import_react6.default.createElement("div", { className: "text-[13px] text-neutral-500" }, mode === "LOGIN" ? /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, "Don't have an account? ", /* @__PURE__ */ import_react6.default.createElement("button", { type: "button", onClick: () => {
531
+ return /* @__PURE__ */ import_react6.default.createElement("div", { className: "w-full max-w-md mx-auto flex flex-col items-center gap-4 relative z-10 animate-in fade-in duration-300" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "w-full bg-white rounded-2xl overflow-hidden" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "p-8 md:p-12" }, step === "INPUT" && /* @__PURE__ */ import_react6.default.createElement("div", { className: "animate-in fade-in duration-300" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "mb-12 text-center mt-2" }, /* @__PURE__ */ import_react6.default.createElement("h2", { className: "text-xl text-black mb-2 tracking-tight" }, mode === "LOGIN" ? `${companyName} ${workspaceLabel}` : "Create Account"), /* @__PURE__ */ import_react6.default.createElement("div", { className: "text-[13px] text-neutral-500" }, mode === "LOGIN" ? /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, "Don't have an account? ", /* @__PURE__ */ import_react6.default.createElement("button", { type: "button", onClick: () => {
513
532
  setMode("SIGNUP");
514
533
  setSignupStep(getInitialSignupStep());
515
534
  }, className: "text-black transition-colors ml-1" }, "Sign up")) : /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, "Already have an account? ", /* @__PURE__ */ import_react6.default.createElement("button", { type: "button", onClick: () => setMode("LOGIN"), className: "text-black transition-colors ml-1" }, "Log in")))), /* @__PURE__ */ import_react6.default.createElement("form", { className: "space-y-6", autoComplete: "off", onSubmit: (e) => {
@@ -517,69 +536,7 @@ function AuthFormInner({
517
536
  if (mode === "SIGNUP" && signupStep === "NAME") handleNextSignupStep();
518
537
  else if (mode === "SIGNUP" && signupStep === "ORGANIZATION") handleNextSignupStep();
519
538
  else handleAuthRequestSubmit();
520
- } }, mode === "SIGNUP" && signupStep === "NAME" && requireNames && /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex flex-col gap-6" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react6.default.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "First Name"), /* @__PURE__ */ import_react6.default.createElement(
521
- "input",
522
- {
523
- type: "text",
524
- value: firstName,
525
- onChange: (e) => setFirstName(cleanAlpha(e.target.value)),
526
- required: true,
527
- autoFocus: true,
528
- className: "w-full px-2 py-3 text-sm bg-transparent border-b border-neutral-100 text-black outline-none focus:border-black transition-all duration-300",
529
- placeholder: "First name"
530
- }
531
- )), /* @__PURE__ */ import_react6.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react6.default.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Last Name"), /* @__PURE__ */ import_react6.default.createElement(
532
- "input",
533
- {
534
- type: "text",
535
- value: lastName,
536
- onChange: (e) => setLastName(cleanAlpha(e.target.value)),
537
- required: true,
538
- className: "w-full px-2 py-3 bg-transparent text-sm border-b border-neutral-100 text-black outline-none focus:border-black transition-all duration-300",
539
- placeholder: "Last name"
540
- }
541
- ))), mode === "SIGNUP" && signupStep === "ORGANIZATION" && requireOrganization && /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex flex-col gap-6" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react6.default.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Organization Name"), /* @__PURE__ */ import_react6.default.createElement(
542
- "input",
543
- {
544
- type: "text",
545
- value: orgName,
546
- onChange: (e) => setOrgName(cleanOrgName(e.target.value)),
547
- required: true,
548
- autoFocus: true,
549
- className: "w-full px-2 py-3 text-sm bg-transparent border-b border-neutral-100 text-black outline-none focus:border-black transition-all duration-300",
550
- placeholder: "Acme Corporation"
551
- }
552
- ))), (mode === "LOGIN" || mode === "SIGNUP" && signupStep === "EMAIL_ID") && /* @__PURE__ */ import_react6.default.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react6.default.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Email ID"), /* @__PURE__ */ import_react6.default.createElement(
553
- "input",
554
- {
555
- type: "email",
556
- value: emailId,
557
- onChange: (e) => setEmailId(cleanEmailId(e.target.value)),
558
- required: true,
559
- autoFocus: true,
560
- className: "w-full px-2 py-3 bg-transparent text-sm border-b border-neutral-100 text-black outline-none focus:border-black transition-all duration-300",
561
- placeholder: "name@company.com"
562
- }
563
- )), mode === "SIGNUP" && /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex items-start gap-3 mt-4" }, /* @__PURE__ */ import_react6.default.createElement(
564
- "input",
565
- {
566
- type: "checkbox",
567
- id: "zairus-terms",
568
- checked: agreedToTerms,
569
- onChange: (e) => setAgreedToTerms(e.target.checked),
570
- className: "mt-0.5 w-4 h-4 bg-white border-neutral-300 rounded text-black focus:ring-black cursor-pointer",
571
- required: true
572
- }
573
- ), /* @__PURE__ */ import_react6.default.createElement("label", { htmlFor: "zairus-terms", className: "text-[11px] text-neutral-500 cursor-pointer leading-snug" }, "I agree to ", companyName, "'s ", /* @__PURE__ */ import_react6.default.createElement("a", { href: termsUrl, target: "_blank", rel: "noreferrer", className: "text-black underline " }, "Terms of Service"), " and ", /* @__PURE__ */ import_react6.default.createElement("a", { href: privacyUrl, target: "_blank", rel: "noreferrer", className: "text-black underline " }, "Privacy Policy"), "."))), /* @__PURE__ */ import_react6.default.createElement(
574
- ThreeDActionButton,
575
- {
576
- type: "submit",
577
- disabled: isContinueDisabled(),
578
- isLoading: isSubmitting,
579
- className: "w-full mt-10"
580
- },
581
- "Continue"
582
- ))), step === "OTP" && /* @__PURE__ */ import_react6.default.createElement("div", { className: "animate-in fade-in duration-300" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "text-center mb-10 mt-2" }, /* @__PURE__ */ import_react6.default.createElement("h2", { className: " text-xl text-black mb-2 tracking-tight " }, "Security Check"), /* @__PURE__ */ import_react6.default.createElement("p", { className: "text-[13px] text-neutral-500" }, "Enter the code sent to ", /* @__PURE__ */ import_react6.default.createElement("br", null), /* @__PURE__ */ import_react6.default.createElement("span", { className: "text-black " }, emailId))), /* @__PURE__ */ import_react6.default.createElement("form", { className: "space-y-10", autoComplete: "off", onSubmit: (e) => {
539
+ } }, mode === "SIGNUP" && signupStep === "NAME" && requireNames && /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex flex-col gap-6" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react6.default.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "First Name"), /* @__PURE__ */ import_react6.default.createElement("input", { type: "text", value: firstName, onChange: (e) => setFirstName(cleanAlpha(e.target.value)), required: true, autoFocus: true, className: "w-full px-2 py-3 text-sm bg-transparent border-b border-neutral-100 text-black outline-none focus:border-black transition-all duration-300", placeholder: "First name" })), /* @__PURE__ */ import_react6.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react6.default.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Last Name"), /* @__PURE__ */ import_react6.default.createElement("input", { type: "text", value: lastName, onChange: (e) => setLastName(cleanAlpha(e.target.value)), required: true, className: "w-full px-2 py-3 bg-transparent text-sm border-b border-neutral-100 text-black outline-none focus:border-black transition-all duration-300", placeholder: "Last name" }))), mode === "SIGNUP" && signupStep === "ORGANIZATION" && requireOrganization && /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex flex-col gap-6" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react6.default.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Organization Name"), /* @__PURE__ */ import_react6.default.createElement("input", { type: "text", value: orgName, onChange: (e) => setOrgName(cleanOrgName(e.target.value)), required: true, autoFocus: true, className: "w-full px-2 py-3 text-sm bg-transparent border-b border-neutral-100 text-black outline-none focus:border-black transition-all duration-300", placeholder: "Acme Corporation" }))), (mode === "LOGIN" || mode === "SIGNUP" && signupStep === "EMAIL_ID") && /* @__PURE__ */ import_react6.default.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react6.default.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Email ID"), /* @__PURE__ */ import_react6.default.createElement("input", { type: "email", value: emailId, onChange: (e) => setEmailId(cleanEmailId(e.target.value)), required: true, autoFocus: true, className: "w-full px-2 py-3 bg-transparent text-sm border-b border-neutral-100 text-black outline-none focus:border-black transition-all duration-300", placeholder: "name@company.com" })), mode === "SIGNUP" && /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex items-start gap-3 mt-4" }, /* @__PURE__ */ import_react6.default.createElement("input", { type: "checkbox", id: "zairus-terms", checked: agreedToTerms, onChange: (e) => setAgreedToTerms(e.target.checked), className: "mt-0.5 w-4 h-4 bg-white border-neutral-300 rounded text-black focus:ring-black cursor-pointer", required: true }), /* @__PURE__ */ import_react6.default.createElement("label", { htmlFor: "zairus-terms", className: "text-[11px] text-neutral-500 cursor-pointer leading-snug" }, "I agree to ", companyName, "'s ", /* @__PURE__ */ import_react6.default.createElement("a", { href: termsUrl, target: "_blank", rel: "noreferrer", className: "text-black underline " }, "Terms of Service"), " and ", /* @__PURE__ */ import_react6.default.createElement("a", { href: privacyUrl, target: "_blank", rel: "noreferrer", className: "text-black underline " }, "Privacy Policy"), "."))), /* @__PURE__ */ import_react6.default.createElement(ThreeDActionButton, { type: "submit", disabled: isContinueDisabled(), isLoading: isSubmitting, className: "w-full mt-10" }, "Continue"))), step === "OTP" && /* @__PURE__ */ import_react6.default.createElement("div", { className: "animate-in fade-in duration-300" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "text-center mb-10 mt-2" }, /* @__PURE__ */ import_react6.default.createElement("h2", { className: "text-xl text-black mb-2 tracking-tight" }, "Security Check"), /* @__PURE__ */ import_react6.default.createElement("p", { className: "text-[13px] text-neutral-500" }, userHas2FA ? "Enter the code from your authenticator app." : `Enter the code sent to ${emailId}`)), /* @__PURE__ */ import_react6.default.createElement("form", { className: "space-y-8", autoComplete: "off", onSubmit: (e) => {
583
540
  e.preventDefault();
584
541
  verifyOtpCode(otp.join(""));
585
542
  } }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex justify-between gap-2", onPaste: handlePaste }, otp.map((digit, index) => /* @__PURE__ */ import_react6.default.createElement(
@@ -594,17 +551,19 @@ function AuthFormInner({
594
551
  maxLength: 1,
595
552
  value: digit,
596
553
  onChange: (e) => handleOtpChange(index, e.target.value),
597
- className: "w-8 h-8 text-center text-lg bg-transparent border-b-2 border-neutral-100 text-black outline-none focus:border-black transition-all duration-300"
554
+ onKeyDown: (e) => {
555
+ if (e.key === "Backspace" && !otp[index] && index > 0) inputRefs.current[index - 1]?.focus();
556
+ },
557
+ className: "w-10 h-12 text-center text-lg bg-transparent border-b-2 border-neutral-100 text-black outline-none focus:border-black transition-all duration-300"
598
558
  }
599
- ))), /* @__PURE__ */ import_react6.default.createElement(
600
- ThreeDActionButton,
559
+ ))), /* @__PURE__ */ import_react6.default.createElement(ThreeDActionButton, { type: "submit", disabled: otp.join("").length < 6, isLoading: isSubmitting, className: "w-full" }, "Verify Code")), userHasPasskey && /* @__PURE__ */ import_react6.default.createElement("div", { className: "pt-6 " }, /* @__PURE__ */ import_react6.default.createElement(
560
+ "button",
601
561
  {
602
- type: "submit",
603
- disabled: otp.join("").length < 6,
604
- isLoading: isSubmitting,
605
- className: "w-full"
562
+ onClick: triggerPasskeyLogin,
563
+ disabled: isSubmitting,
564
+ className: "w-full py-2.5 rounded-full text-black border border-neutral-200 hover:bg-neutral-50 text-xs font-medium tracking-wide transition-colors outline-none disabled:opacity-50"
606
565
  },
607
- "Verify Code"
566
+ "Use Passkey / Biometrics"
608
567
  ))))));
609
568
  }
610
569
  var PipleAuth = (props) => {
@@ -1201,7 +1160,7 @@ var UniversalProfileSettings = ({
1201
1160
  type: "submit",
1202
1161
  disabled: isPinSubmitting || newPin.length !== 4 || confirmPin.length !== 4 || hasPin && oldPin.length !== 4,
1203
1162
  isLoading: isPinSubmitting,
1204
- className: "w-full py-3"
1163
+ className: "w-full"
1205
1164
  },
1206
1165
  hasPin ? "Update PIN" : "Set PIN"
1207
1166
  ))))))));
@@ -1462,14 +1421,14 @@ var UniversalTransactionPage = ({
1462
1421
  {
1463
1422
  onClick: handleGenerateReceipt,
1464
1423
  isLoading: isGeneratingReceipt,
1465
- className: "w-full py-3 text-[14px]"
1424
+ className: "w-full"
1466
1425
  },
1467
1426
  "Generate Receipt"
1468
1427
  ), /* @__PURE__ */ import_react23.default.createElement(
1469
1428
  "button",
1470
1429
  {
1471
1430
  onClick: () => onReportTransaction && onReportTransaction(selectedTransaction),
1472
- className: "w-full flex items-center justify-center py-2.5 rounded-full border border-neutral-200 text-black hover:bg-neutral-50 transition-colors outline-none text-[13px] tracking-wide mt-2"
1431
+ className: "w-full flex items-center justify-center py-2.5 rounded-full border border-neutral-200 text-black hover:bg-neutral-50 transition-colors outline-none text-xs tracking-wide mt-2"
1473
1432
  },
1474
1433
  "Report Transaction"
1475
1434
  ), selectedTransaction.type === "WALLET_TRANSACTION" && /* @__PURE__ */ import_react23.default.createElement(
@@ -1478,7 +1437,7 @@ var UniversalTransactionPage = ({
1478
1437
  href: `https://basescan.org/tx/${selectedTransaction.reference}`,
1479
1438
  target: "_blank",
1480
1439
  rel: "noopener noreferrer",
1481
- className: "w-full flex items-center justify-center py-2.5 rounded-full border border-neutral-200 text-black hover:bg-neutral-50 transition-colors outline-none text-[13px] tracking-wide mt-2"
1440
+ className: "w-full flex items-center justify-center py-2.5 rounded-full border border-neutral-200 text-black hover:bg-neutral-50 transition-colors outline-none text-xs tracking-wide mt-2"
1482
1441
  },
1483
1442
  "View in block explorer"
1484
1443
  ))))), isDirectionModalOpen && /* @__PURE__ */ import_react23.default.createElement("div", { className: "fixed inset-0 z-110 flex items-center justify-center p-4" }, /* @__PURE__ */ import_react23.default.createElement("div", { className: "absolute inset-0 bg-black/40 ", onClick: () => setIsDirectionModalOpen(false) }), /* @__PURE__ */ import_react23.default.createElement("div", { ref: directionDropdownRef, className: "relative w-72 bg-white shadow-2xl rounded-2xl flex flex-col items-center overflow-hidden animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ import_react23.default.createElement("div", { className: "p-6 text-center w-full mb-2" }, /* @__PURE__ */ import_react23.default.createElement("h3", { className: "text-[14px] text-black tracking-tight" }, "Payment Type")), /* @__PURE__ */ import_react23.default.createElement("div", { className: "w-full flex flex-col pl-2 pr-2 gap-1" }, ["ALL", "CREDIT", "DEBIT"].map((option) => /* @__PURE__ */ import_react23.default.createElement(
@@ -1578,7 +1537,7 @@ var UniversalHomeView = ({
1578
1537
  ThreeDActionButton,
1579
1538
  {
1580
1539
  onClick: primaryAction.onClick,
1581
- className: "px-6 py-2.5 sm:px-8 sm:py-2.5"
1540
+ className: "px-6 sm:px-8"
1582
1541
  },
1583
1542
  /* @__PURE__ */ import_react25.default.createElement("span", { className: "flex items-center gap-1.5 text-[13px] tracking-wide " }, primaryAction.label, primaryAction.icon && /* @__PURE__ */ import_react25.default.createElement(import_react26.HugeiconsIcon, { icon: primaryAction.icon, size: 16 }))
1584
1543
  ), secondaryAction && /* @__PURE__ */ import_react25.default.createElement(
@@ -1690,14 +1649,14 @@ var UniversalWalletPage = ({
1690
1649
  {
1691
1650
  onClick: () => onDownloadPayId && onDownloadPayId(selectedWallet),
1692
1651
  isLoading: isGeneratingStatement,
1693
- className: "w-full py-3 text-[13px]"
1652
+ className: "w-full"
1694
1653
  },
1695
1654
  "Generate Statement"
1696
1655
  ), /* @__PURE__ */ import_react27.default.createElement(
1697
1656
  "button",
1698
1657
  {
1699
1658
  onClick: () => handleCopy(selectedWallet),
1700
- className: "w-full flex items-center justify-center py-2.5 rounded-full border border-neutral-200 text-black hover:bg-neutral-50 outline-none text-[13px] tracking-wide transition-colors"
1659
+ className: "w-full flex items-center justify-center py-2.5 rounded-full border border-neutral-200 text-black hover:bg-neutral-50 outline-none text-xs tracking-wide transition-colors"
1701
1660
  },
1702
1661
  "Copy Wallet Address"
1703
1662
  )))))));
@@ -2665,7 +2624,7 @@ var import_react45 = __toESM(require("react"));
2665
2624
  var import_react_hot_toast8 = __toESM(require("react-hot-toast"));
2666
2625
  var import_react46 = require("@hugeicons/react");
2667
2626
  var import_core_free_icons16 = require("@hugeicons/core-free-icons");
2668
- var import_browser = require("@simplewebauthn/browser");
2627
+ var import_browser2 = require("@simplewebauthn/browser");
2669
2628
  var UniversalSecurityPage = ({
2670
2629
  has2FA,
2671
2630
  hasPasskey,
@@ -2810,7 +2769,7 @@ var UniversalSecurityPage = ({
2810
2769
  const options = await onRequestPasskeySetup();
2811
2770
  let credentialResponse;
2812
2771
  try {
2813
- credentialResponse = await (0, import_browser.startRegistration)({ optionsJSON: options });
2772
+ credentialResponse = await (0, import_browser2.startRegistration)({ optionsJSON: options });
2814
2773
  } catch (err) {
2815
2774
  if (err.name === "NotAllowedError") {
2816
2775
  throw new Error("Passkey setup was canceled or is not supported on this device.");
@@ -2861,7 +2820,15 @@ var UniversalSecurityPage = ({
2861
2820
  toggleLoading: isPasskeyLoading,
2862
2821
  isLast: true
2863
2822
  }
2864
- ))), show2FASetupModal && /* @__PURE__ */ import_react45.default.createElement("div", { className: "fixed inset-0 z-120 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "absolute inset-0 bg-black/40 ", onClick: () => !isSubmitting && setShow2FASetupModal(false) }), /* @__PURE__ */ import_react45.default.createElement("div", { className: "relative w-full max-w-sm bg-white rounded-2xl flex flex-col overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200 max-h-[90vh]" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "flex items-center justify-between p-5 shrink-0 " }, /* @__PURE__ */ import_react45.default.createElement("h3", { className: "text-[15px] text-black tracking-tight" }, "Enable 2FA"), /* @__PURE__ */ import_react45.default.createElement("button", { onClick: () => !isSubmitting && setShow2FASetupModal(false), className: "text-neutral-400 hover:text-black transition-colors outline-none" }, /* @__PURE__ */ import_react45.default.createElement(import_react46.HugeiconsIcon, { icon: import_core_free_icons16.CancelCircleIcon, size: 18 }))), /* @__PURE__ */ import_react45.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 pt-2" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "w-full flex justify-center mb-6 mix-blend-multiply" }, twoFaQr ? /* @__PURE__ */ import_react45.default.createElement("img", { src: twoFaQr, alt: "2FA QR Code", className: "w-40 h-40 object-contain rounded-xl border border-neutral-100 p-2" }) : /* @__PURE__ */ import_react45.default.createElement("div", { className: "w-40 h-40 bg-neutral-100 rounded-xl flex items-center justify-center animate-pulse" })), /* @__PURE__ */ import_react45.default.createElement("div", { className: "text-center mb-8 mt-2" }, /* @__PURE__ */ import_react45.default.createElement("h2", { className: "text-xl text-black mb-2 tracking-tight" }, "Security Check"), /* @__PURE__ */ import_react45.default.createElement("p", { className: "text-[13px] text-neutral-500" }, "Enter the 6-digit code from your app")), /* @__PURE__ */ import_react45.default.createElement("form", { className: "space-y-4", autoComplete: "off", onSubmit: (e) => {
2823
+ ))), show2FASetupModal && /* @__PURE__ */ import_react45.default.createElement("div", { className: "fixed inset-0 z-120 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "absolute inset-0 bg-black/40 ", onClick: () => !isSubmitting && setShow2FASetupModal(false) }), /* @__PURE__ */ import_react45.default.createElement("div", { className: "relative w-full max-w-sm bg-white rounded-2xl flex flex-col overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200 max-h-[90vh]" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "flex items-center justify-between p-5 shrink-0 " }, /* @__PURE__ */ import_react45.default.createElement("h3", { className: "text-[15px] text-black tracking-tight" }, "Enable 2FA"), /* @__PURE__ */ import_react45.default.createElement("button", { onClick: () => !isSubmitting && setShow2FASetupModal(false), className: "text-neutral-400 hover:text-black transition-colors outline-none" }, /* @__PURE__ */ import_react45.default.createElement(import_react46.HugeiconsIcon, { icon: import_core_free_icons16.CancelCircleIcon, size: 18 }))), /* @__PURE__ */ import_react45.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 pt-2" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "w-full flex justify-center mb-6 mix-blend-multiply" }, twoFaQr ? /* @__PURE__ */ import_react45.default.createElement("img", { src: twoFaQr, alt: "2FA QR Code", className: "w-40 h-40 object-contain rounded-xl border border-neutral-100 p-2" }) : /* @__PURE__ */ import_react45.default.createElement("div", { className: "w-40 h-40 bg-neutral-100 rounded-xl flex items-center justify-center animate-pulse" })), /* @__PURE__ */ import_react45.default.createElement("div", { className: "grid grid-cols-1 gap-y-6 gap-x-4 mb-8" }, /* @__PURE__ */ import_react45.default.createElement("div", null, /* @__PURE__ */ import_react45.default.createElement("span", { className: "text-[11px] tracking-[0.2em] text-neutral-400 block mb-2 uppercase" }, "Setup Key"), /* @__PURE__ */ import_react45.default.createElement("div", { className: "flex items-center gap-2 min-w-0 bg-neutral-50 px-3 py-2.5 rounded-xl " }, /* @__PURE__ */ import_react45.default.createElement("span", { className: "text-[13px] font-mono tracking-widest text-black truncate min-w-0 block flex-1" }, twoFaSecret), /* @__PURE__ */ import_react45.default.createElement(
2824
+ "button",
2825
+ {
2826
+ type: "button",
2827
+ onClick: () => handleCopySecret(twoFaSecret),
2828
+ className: "text-neutral-400 hover:text-black transition-colors outline-none shrink-0 ml-2"
2829
+ },
2830
+ /* @__PURE__ */ import_react45.default.createElement(import_react46.HugeiconsIcon, { icon: import_core_free_icons16.Copy01Icon, size: 16 })
2831
+ )))), /* @__PURE__ */ import_react45.default.createElement("div", { className: "text-center mb-8 mt-2" }, /* @__PURE__ */ import_react45.default.createElement("h2", { className: "text-xl text-black mb-2 tracking-tight" }, "Security Check"), /* @__PURE__ */ import_react45.default.createElement("p", { className: "text-[13px] text-neutral-500" }, "Enter the 6-digit code from your app")), /* @__PURE__ */ import_react45.default.createElement("form", { className: "space-y-4", autoComplete: "off", onSubmit: (e) => {
2865
2832
  e.preventDefault();
2866
2833
  submitEnable2FA(otp.join(""));
2867
2834
  } }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "flex justify-between gap-2 pb-6", onPaste: handlePaste }, otp.map((digit, index) => /* @__PURE__ */ import_react45.default.createElement(
@@ -2897,7 +2864,7 @@ var UniversalSecurityPage = ({
2897
2864
  {
2898
2865
  type: "button",
2899
2866
  onClick: () => handleCopySecret(twoFaSecret),
2900
- className: "w-full flex items-center justify-center py-3 rounded-full bg-neutral-100 text-black hover:bg-neutral-200 outline-none text-[13px] font-medium tracking-wide transition-colors mt-3"
2867
+ className: "w-full flex items-center justify-center py-2.5 rounded-full border border-neutral-200 text-black hover:bg-neutral-50 outline-none text-xs font-medium tracking-wide transition-colors mt-2"
2901
2868
  },
2902
2869
  /* @__PURE__ */ import_react45.default.createElement(import_react46.HugeiconsIcon, { icon: import_core_free_icons16.Copy01Icon, size: 16, className: "mr-2" }),
2903
2870
  "Copy Secret Key"
@@ -2932,7 +2899,7 @@ var UniversalSecurityPage = ({
2932
2899
  className: "w-full py-3.5"
2933
2900
  },
2934
2901
  "Verify & Disable"
2935
- ))))), showPasskeyModal && /* @__PURE__ */ import_react45.default.createElement("div", { className: "fixed inset-0 z-120 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "absolute inset-0 bg-black/40 ", onClick: () => !isSubmitting && setShowPasskeyModal(false) }), /* @__PURE__ */ import_react45.default.createElement("div", { className: "relative w-full max-w-sm bg-white rounded-2xl flex flex-col overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "flex items-center justify-between p-5 shrink-0" }, /* @__PURE__ */ import_react45.default.createElement("h3", { className: "text-[15px] text-black tracking-tight" }, "Enable Passkey"), /* @__PURE__ */ import_react45.default.createElement("button", { onClick: () => !isSubmitting && setShowPasskeyModal(false), className: "text-neutral-400 hover:text-black transition-colors outline-none" }, /* @__PURE__ */ import_react45.default.createElement(import_react46.HugeiconsIcon, { icon: import_core_free_icons16.CancelCircleIcon, size: 18 }))), /* @__PURE__ */ import_react45.default.createElement("div", { className: "p-6 text-center" }, /* @__PURE__ */ import_react45.default.createElement("p", { className: "text-[13px] text-neutral-500 mb-8 leading-relaxed" }, "Use your device's biometrics (Face ID, Touch ID, or PIN) to securely sign into your account without needing a password."), /* @__PURE__ */ import_react45.default.createElement(
2902
+ ))))), showPasskeyModal && /* @__PURE__ */ import_react45.default.createElement("div", { className: "fixed inset-0 z-120 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "absolute inset-0 bg-black/40 ", onClick: () => !isSubmitting && setShowPasskeyModal(false) }), /* @__PURE__ */ import_react45.default.createElement("div", { className: "relative w-full max-w-sm bg-white rounded-2xl flex flex-col overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "flex items-center justify-between p-5 shrink-0" }, /* @__PURE__ */ import_react45.default.createElement("h3", { className: "text-[15px] text-black tracking-tight" }, "Enable Passkey"), /* @__PURE__ */ import_react45.default.createElement("button", { onClick: () => !isSubmitting && setShowPasskeyModal(false), className: "text-neutral-400 hover:text-black transition-colors outline-none" }, /* @__PURE__ */ import_react45.default.createElement(import_react46.HugeiconsIcon, { icon: import_core_free_icons16.CancelCircleIcon, size: 18 }))), /* @__PURE__ */ import_react45.default.createElement("div", { className: "p-6 text-center" }, /* @__PURE__ */ import_react45.default.createElement("h2", { className: "text-lg text-black mb-2 tracking-tight" }, "Simplify your Sign In"), /* @__PURE__ */ import_react45.default.createElement("p", { className: "text-[13px] text-neutral-500 mb-8 leading-relaxed" }, "Use your device's biometrics (Face ID, Touch ID, or PIN) to securely sign into your account without needing a password."), /* @__PURE__ */ import_react45.default.createElement(
2936
2903
  ThreeDActionButton,
2937
2904
  {
2938
2905
  onClick: submitEnablePasskey,
package/dist/index.mjs CHANGED
@@ -297,6 +297,7 @@ import React5, { useState as useState3, useRef as useRef2, useEffect as useEffec
297
297
  import { useSearchParams } from "next/navigation";
298
298
  import toast from "react-hot-toast";
299
299
  import { useGoogleReCaptcha, GoogleReCaptchaProvider } from "react-google-recaptcha-v3";
300
+ import { startAuthentication } from "@simplewebauthn/browser";
300
301
  var InputSpinner = () => /* @__PURE__ */ React5.createElement("svg", { className: "animate-spin h-4 w-4 text-neutral-400", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24" }, /* @__PURE__ */ React5.createElement("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), /* @__PURE__ */ React5.createElement("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" }));
301
302
  function AuthFormInner({
302
303
  companyName,
@@ -328,6 +329,9 @@ function AuthFormInner({
328
329
  const [lastName, setLastName] = useState3("");
329
330
  const [orgName, setOrgName] = useState3("");
330
331
  const [agreedToTerms, setAgreedToTerms] = useState3(false);
332
+ const [userHas2FA, setUserHas2FA] = useState3(false);
333
+ const [userHasPasskey, setUserHasPasskey] = useState3(false);
334
+ const [authOptions, setAuthOptions] = useState3(null);
331
335
  const [otp, setOtp] = useState3(["", "", "", "", "", ""]);
332
336
  const inputRefs = useRef2([]);
333
337
  const cleanAlpha = (val) => val.replace(/[^a-zA-Z\s-]/g, "");
@@ -345,9 +349,7 @@ function AuthFormInner({
345
349
  const newOtp = [...otp];
346
350
  newOtp[index] = cleanValue.slice(-1);
347
351
  setOtp(newOtp);
348
- if (cleanValue && index < 5) {
349
- inputRefs.current[index + 1]?.focus();
350
- }
352
+ if (cleanValue && index < 5) inputRefs.current[index + 1]?.focus();
351
353
  };
352
354
  const handlePaste = (e) => {
353
355
  e.preventDefault();
@@ -356,13 +358,10 @@ function AuthFormInner({
356
358
  if (!numbersOnly) return;
357
359
  const newOtp = [...otp];
358
360
  const length = Math.min(numbersOnly.length, 6);
359
- for (let i = 0; i < length; i++) {
360
- newOtp[i] = numbersOnly[i];
361
- }
361
+ for (let i = 0; i < length; i++) newOtp[i] = numbersOnly[i];
362
362
  setOtp(newOtp);
363
- if (length < 6) {
364
- inputRefs.current[length]?.focus();
365
- } else {
363
+ if (length < 6) inputRefs.current[length]?.focus();
364
+ else {
366
365
  inputRefs.current[5]?.focus();
367
366
  verifyOtpCode(newOtp.join(""));
368
367
  }
@@ -389,7 +388,10 @@ function AuthFormInner({
389
388
  recaptchaToken
390
389
  });
391
390
  if (res.success) {
392
- toast.success("Verification code sent");
391
+ setUserHas2FA(!!res.has2FA);
392
+ setUserHasPasskey(!!res.hasPasskey);
393
+ if (res.passkeyOptions) setAuthOptions(res.passkeyOptions);
394
+ toast.success(res.has2FA ? "Security check required" : "Verification code sent");
393
395
  setStep("OTP");
394
396
  setCountdown(60);
395
397
  } else {
@@ -419,6 +421,23 @@ function AuthFormInner({
419
421
  setIsSubmitting(false);
420
422
  }
421
423
  };
424
+ const triggerPasskeyLogin = async () => {
425
+ if (!authOptions || isSubmitting) return;
426
+ setIsSubmitting(true);
427
+ try {
428
+ const credentialResponse = await startAuthentication({ optionsJSON: authOptions });
429
+ const res = await onVerifyOtp({ email: emailId, isPasskey: true, passkeyCredential: credentialResponse });
430
+ if (res.success) {
431
+ window.location.href = res.redirect || redirectUrl;
432
+ } else {
433
+ toast.error(res.error || "Device verification failed.");
434
+ }
435
+ } catch (err) {
436
+ if (err.name !== "NotAllowedError") toast.error("Passkey verification interrupted.");
437
+ } finally {
438
+ setIsSubmitting(false);
439
+ }
440
+ };
422
441
  const handleNextSignupStep = () => {
423
442
  if (signupStep === "NAME") {
424
443
  if (requireOrganization) setSignupStep("ORGANIZATION");
@@ -437,7 +456,7 @@ function AuthFormInner({
437
456
  }
438
457
  return false;
439
458
  };
440
- return /* @__PURE__ */ React5.createElement("div", { className: "w-full max-w-md mx-auto flex flex-col items-center gap-4 relative z-10 animate-in fade-in duration-300" }, /* @__PURE__ */ React5.createElement("div", { className: "w-full bg-white rounded-2xl overflow-hidden" }, /* @__PURE__ */ React5.createElement("div", { className: "p-8 md:p-12" }, step === "INPUT" && /* @__PURE__ */ React5.createElement("div", { className: "animate-in fade-in duration-300" }, /* @__PURE__ */ React5.createElement("div", { className: "mb-12 text-center mt-2" }, /* @__PURE__ */ React5.createElement("h2", { className: " text-xl text-black mb-2 tracking-tight " }, mode === "LOGIN" ? `${companyName} ${workspaceLabel}` : "Create Account"), /* @__PURE__ */ React5.createElement("div", { className: "text-[13px] text-neutral-500" }, mode === "LOGIN" ? /* @__PURE__ */ React5.createElement(React5.Fragment, null, "Don't have an account? ", /* @__PURE__ */ React5.createElement("button", { type: "button", onClick: () => {
459
+ return /* @__PURE__ */ React5.createElement("div", { className: "w-full max-w-md mx-auto flex flex-col items-center gap-4 relative z-10 animate-in fade-in duration-300" }, /* @__PURE__ */ React5.createElement("div", { className: "w-full bg-white rounded-2xl overflow-hidden" }, /* @__PURE__ */ React5.createElement("div", { className: "p-8 md:p-12" }, step === "INPUT" && /* @__PURE__ */ React5.createElement("div", { className: "animate-in fade-in duration-300" }, /* @__PURE__ */ React5.createElement("div", { className: "mb-12 text-center mt-2" }, /* @__PURE__ */ React5.createElement("h2", { className: "text-xl text-black mb-2 tracking-tight" }, mode === "LOGIN" ? `${companyName} ${workspaceLabel}` : "Create Account"), /* @__PURE__ */ React5.createElement("div", { className: "text-[13px] text-neutral-500" }, mode === "LOGIN" ? /* @__PURE__ */ React5.createElement(React5.Fragment, null, "Don't have an account? ", /* @__PURE__ */ React5.createElement("button", { type: "button", onClick: () => {
441
460
  setMode("SIGNUP");
442
461
  setSignupStep(getInitialSignupStep());
443
462
  }, className: "text-black transition-colors ml-1" }, "Sign up")) : /* @__PURE__ */ React5.createElement(React5.Fragment, null, "Already have an account? ", /* @__PURE__ */ React5.createElement("button", { type: "button", onClick: () => setMode("LOGIN"), className: "text-black transition-colors ml-1" }, "Log in")))), /* @__PURE__ */ React5.createElement("form", { className: "space-y-6", autoComplete: "off", onSubmit: (e) => {
@@ -445,69 +464,7 @@ function AuthFormInner({
445
464
  if (mode === "SIGNUP" && signupStep === "NAME") handleNextSignupStep();
446
465
  else if (mode === "SIGNUP" && signupStep === "ORGANIZATION") handleNextSignupStep();
447
466
  else handleAuthRequestSubmit();
448
- } }, mode === "SIGNUP" && signupStep === "NAME" && requireNames && /* @__PURE__ */ React5.createElement("div", { className: "flex flex-col gap-6" }, /* @__PURE__ */ React5.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React5.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "First Name"), /* @__PURE__ */ React5.createElement(
449
- "input",
450
- {
451
- type: "text",
452
- value: firstName,
453
- onChange: (e) => setFirstName(cleanAlpha(e.target.value)),
454
- required: true,
455
- autoFocus: true,
456
- className: "w-full px-2 py-3 text-sm bg-transparent border-b border-neutral-100 text-black outline-none focus:border-black transition-all duration-300",
457
- placeholder: "First name"
458
- }
459
- )), /* @__PURE__ */ React5.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React5.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Last Name"), /* @__PURE__ */ React5.createElement(
460
- "input",
461
- {
462
- type: "text",
463
- value: lastName,
464
- onChange: (e) => setLastName(cleanAlpha(e.target.value)),
465
- required: true,
466
- className: "w-full px-2 py-3 bg-transparent text-sm border-b border-neutral-100 text-black outline-none focus:border-black transition-all duration-300",
467
- placeholder: "Last name"
468
- }
469
- ))), mode === "SIGNUP" && signupStep === "ORGANIZATION" && requireOrganization && /* @__PURE__ */ React5.createElement("div", { className: "flex flex-col gap-6" }, /* @__PURE__ */ React5.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ React5.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Organization Name"), /* @__PURE__ */ React5.createElement(
470
- "input",
471
- {
472
- type: "text",
473
- value: orgName,
474
- onChange: (e) => setOrgName(cleanOrgName(e.target.value)),
475
- required: true,
476
- autoFocus: true,
477
- className: "w-full px-2 py-3 text-sm bg-transparent border-b border-neutral-100 text-black outline-none focus:border-black transition-all duration-300",
478
- placeholder: "Acme Corporation"
479
- }
480
- ))), (mode === "LOGIN" || mode === "SIGNUP" && signupStep === "EMAIL_ID") && /* @__PURE__ */ React5.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React5.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React5.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Email ID"), /* @__PURE__ */ React5.createElement(
481
- "input",
482
- {
483
- type: "email",
484
- value: emailId,
485
- onChange: (e) => setEmailId(cleanEmailId(e.target.value)),
486
- required: true,
487
- autoFocus: true,
488
- className: "w-full px-2 py-3 bg-transparent text-sm border-b border-neutral-100 text-black outline-none focus:border-black transition-all duration-300",
489
- placeholder: "name@company.com"
490
- }
491
- )), mode === "SIGNUP" && /* @__PURE__ */ React5.createElement("div", { className: "flex items-start gap-3 mt-4" }, /* @__PURE__ */ React5.createElement(
492
- "input",
493
- {
494
- type: "checkbox",
495
- id: "zairus-terms",
496
- checked: agreedToTerms,
497
- onChange: (e) => setAgreedToTerms(e.target.checked),
498
- className: "mt-0.5 w-4 h-4 bg-white border-neutral-300 rounded text-black focus:ring-black cursor-pointer",
499
- required: true
500
- }
501
- ), /* @__PURE__ */ React5.createElement("label", { htmlFor: "zairus-terms", className: "text-[11px] text-neutral-500 cursor-pointer leading-snug" }, "I agree to ", companyName, "'s ", /* @__PURE__ */ React5.createElement("a", { href: termsUrl, target: "_blank", rel: "noreferrer", className: "text-black underline " }, "Terms of Service"), " and ", /* @__PURE__ */ React5.createElement("a", { href: privacyUrl, target: "_blank", rel: "noreferrer", className: "text-black underline " }, "Privacy Policy"), "."))), /* @__PURE__ */ React5.createElement(
502
- ThreeDActionButton,
503
- {
504
- type: "submit",
505
- disabled: isContinueDisabled(),
506
- isLoading: isSubmitting,
507
- className: "w-full mt-10"
508
- },
509
- "Continue"
510
- ))), step === "OTP" && /* @__PURE__ */ React5.createElement("div", { className: "animate-in fade-in duration-300" }, /* @__PURE__ */ React5.createElement("div", { className: "text-center mb-10 mt-2" }, /* @__PURE__ */ React5.createElement("h2", { className: " text-xl text-black mb-2 tracking-tight " }, "Security Check"), /* @__PURE__ */ React5.createElement("p", { className: "text-[13px] text-neutral-500" }, "Enter the code sent to ", /* @__PURE__ */ React5.createElement("br", null), /* @__PURE__ */ React5.createElement("span", { className: "text-black " }, emailId))), /* @__PURE__ */ React5.createElement("form", { className: "space-y-10", autoComplete: "off", onSubmit: (e) => {
467
+ } }, mode === "SIGNUP" && signupStep === "NAME" && requireNames && /* @__PURE__ */ React5.createElement("div", { className: "flex flex-col gap-6" }, /* @__PURE__ */ React5.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React5.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "First Name"), /* @__PURE__ */ React5.createElement("input", { type: "text", value: firstName, onChange: (e) => setFirstName(cleanAlpha(e.target.value)), required: true, autoFocus: true, className: "w-full px-2 py-3 text-sm bg-transparent border-b border-neutral-100 text-black outline-none focus:border-black transition-all duration-300", placeholder: "First name" })), /* @__PURE__ */ React5.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React5.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Last Name"), /* @__PURE__ */ React5.createElement("input", { type: "text", value: lastName, onChange: (e) => setLastName(cleanAlpha(e.target.value)), required: true, className: "w-full px-2 py-3 bg-transparent text-sm border-b border-neutral-100 text-black outline-none focus:border-black transition-all duration-300", placeholder: "Last name" }))), mode === "SIGNUP" && signupStep === "ORGANIZATION" && requireOrganization && /* @__PURE__ */ React5.createElement("div", { className: "flex flex-col gap-6" }, /* @__PURE__ */ React5.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ React5.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Organization Name"), /* @__PURE__ */ React5.createElement("input", { type: "text", value: orgName, onChange: (e) => setOrgName(cleanOrgName(e.target.value)), required: true, autoFocus: true, className: "w-full px-2 py-3 text-sm bg-transparent border-b border-neutral-100 text-black outline-none focus:border-black transition-all duration-300", placeholder: "Acme Corporation" }))), (mode === "LOGIN" || mode === "SIGNUP" && signupStep === "EMAIL_ID") && /* @__PURE__ */ React5.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React5.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React5.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Email ID"), /* @__PURE__ */ React5.createElement("input", { type: "email", value: emailId, onChange: (e) => setEmailId(cleanEmailId(e.target.value)), required: true, autoFocus: true, className: "w-full px-2 py-3 bg-transparent text-sm border-b border-neutral-100 text-black outline-none focus:border-black transition-all duration-300", placeholder: "name@company.com" })), mode === "SIGNUP" && /* @__PURE__ */ React5.createElement("div", { className: "flex items-start gap-3 mt-4" }, /* @__PURE__ */ React5.createElement("input", { type: "checkbox", id: "zairus-terms", checked: agreedToTerms, onChange: (e) => setAgreedToTerms(e.target.checked), className: "mt-0.5 w-4 h-4 bg-white border-neutral-300 rounded text-black focus:ring-black cursor-pointer", required: true }), /* @__PURE__ */ React5.createElement("label", { htmlFor: "zairus-terms", className: "text-[11px] text-neutral-500 cursor-pointer leading-snug" }, "I agree to ", companyName, "'s ", /* @__PURE__ */ React5.createElement("a", { href: termsUrl, target: "_blank", rel: "noreferrer", className: "text-black underline " }, "Terms of Service"), " and ", /* @__PURE__ */ React5.createElement("a", { href: privacyUrl, target: "_blank", rel: "noreferrer", className: "text-black underline " }, "Privacy Policy"), "."))), /* @__PURE__ */ React5.createElement(ThreeDActionButton, { type: "submit", disabled: isContinueDisabled(), isLoading: isSubmitting, className: "w-full mt-10" }, "Continue"))), step === "OTP" && /* @__PURE__ */ React5.createElement("div", { className: "animate-in fade-in duration-300" }, /* @__PURE__ */ React5.createElement("div", { className: "text-center mb-10 mt-2" }, /* @__PURE__ */ React5.createElement("h2", { className: "text-xl text-black mb-2 tracking-tight" }, "Security Check"), /* @__PURE__ */ React5.createElement("p", { className: "text-[13px] text-neutral-500" }, userHas2FA ? "Enter the code from your authenticator app." : `Enter the code sent to ${emailId}`)), /* @__PURE__ */ React5.createElement("form", { className: "space-y-8", autoComplete: "off", onSubmit: (e) => {
511
468
  e.preventDefault();
512
469
  verifyOtpCode(otp.join(""));
513
470
  } }, /* @__PURE__ */ React5.createElement("div", { className: "flex justify-between gap-2", onPaste: handlePaste }, otp.map((digit, index) => /* @__PURE__ */ React5.createElement(
@@ -522,17 +479,19 @@ function AuthFormInner({
522
479
  maxLength: 1,
523
480
  value: digit,
524
481
  onChange: (e) => handleOtpChange(index, e.target.value),
525
- className: "w-8 h-8 text-center text-lg bg-transparent border-b-2 border-neutral-100 text-black outline-none focus:border-black transition-all duration-300"
482
+ onKeyDown: (e) => {
483
+ if (e.key === "Backspace" && !otp[index] && index > 0) inputRefs.current[index - 1]?.focus();
484
+ },
485
+ className: "w-10 h-12 text-center text-lg bg-transparent border-b-2 border-neutral-100 text-black outline-none focus:border-black transition-all duration-300"
526
486
  }
527
- ))), /* @__PURE__ */ React5.createElement(
528
- ThreeDActionButton,
487
+ ))), /* @__PURE__ */ React5.createElement(ThreeDActionButton, { type: "submit", disabled: otp.join("").length < 6, isLoading: isSubmitting, className: "w-full" }, "Verify Code")), userHasPasskey && /* @__PURE__ */ React5.createElement("div", { className: "pt-6 " }, /* @__PURE__ */ React5.createElement(
488
+ "button",
529
489
  {
530
- type: "submit",
531
- disabled: otp.join("").length < 6,
532
- isLoading: isSubmitting,
533
- className: "w-full"
490
+ onClick: triggerPasskeyLogin,
491
+ disabled: isSubmitting,
492
+ className: "w-full py-2.5 rounded-full text-black border border-neutral-200 hover:bg-neutral-50 text-xs font-medium tracking-wide transition-colors outline-none disabled:opacity-50"
534
493
  },
535
- "Verify Code"
494
+ "Use Passkey / Biometrics"
536
495
  ))))));
537
496
  }
538
497
  var PipleAuth = (props) => {
@@ -1143,7 +1102,7 @@ var UniversalProfileSettings = ({
1143
1102
  type: "submit",
1144
1103
  disabled: isPinSubmitting || newPin.length !== 4 || confirmPin.length !== 4 || hasPin && oldPin.length !== 4,
1145
1104
  isLoading: isPinSubmitting,
1146
- className: "w-full py-3"
1105
+ className: "w-full"
1147
1106
  },
1148
1107
  hasPin ? "Update PIN" : "Set PIN"
1149
1108
  ))))))));
@@ -1415,14 +1374,14 @@ var UniversalTransactionPage = ({
1415
1374
  {
1416
1375
  onClick: handleGenerateReceipt,
1417
1376
  isLoading: isGeneratingReceipt,
1418
- className: "w-full py-3 text-[14px]"
1377
+ className: "w-full"
1419
1378
  },
1420
1379
  "Generate Receipt"
1421
1380
  ), /* @__PURE__ */ React15.createElement(
1422
1381
  "button",
1423
1382
  {
1424
1383
  onClick: () => onReportTransaction && onReportTransaction(selectedTransaction),
1425
- className: "w-full flex items-center justify-center py-2.5 rounded-full border border-neutral-200 text-black hover:bg-neutral-50 transition-colors outline-none text-[13px] tracking-wide mt-2"
1384
+ className: "w-full flex items-center justify-center py-2.5 rounded-full border border-neutral-200 text-black hover:bg-neutral-50 transition-colors outline-none text-xs tracking-wide mt-2"
1426
1385
  },
1427
1386
  "Report Transaction"
1428
1387
  ), selectedTransaction.type === "WALLET_TRANSACTION" && /* @__PURE__ */ React15.createElement(
@@ -1431,7 +1390,7 @@ var UniversalTransactionPage = ({
1431
1390
  href: `https://basescan.org/tx/${selectedTransaction.reference}`,
1432
1391
  target: "_blank",
1433
1392
  rel: "noopener noreferrer",
1434
- className: "w-full flex items-center justify-center py-2.5 rounded-full border border-neutral-200 text-black hover:bg-neutral-50 transition-colors outline-none text-[13px] tracking-wide mt-2"
1393
+ className: "w-full flex items-center justify-center py-2.5 rounded-full border border-neutral-200 text-black hover:bg-neutral-50 transition-colors outline-none text-xs tracking-wide mt-2"
1435
1394
  },
1436
1395
  "View in block explorer"
1437
1396
  ))))), isDirectionModalOpen && /* @__PURE__ */ React15.createElement("div", { className: "fixed inset-0 z-110 flex items-center justify-center p-4" }, /* @__PURE__ */ React15.createElement("div", { className: "absolute inset-0 bg-black/40 ", onClick: () => setIsDirectionModalOpen(false) }), /* @__PURE__ */ React15.createElement("div", { ref: directionDropdownRef, className: "relative w-72 bg-white shadow-2xl rounded-2xl flex flex-col items-center overflow-hidden animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ React15.createElement("div", { className: "p-6 text-center w-full mb-2" }, /* @__PURE__ */ React15.createElement("h3", { className: "text-[14px] text-black tracking-tight" }, "Payment Type")), /* @__PURE__ */ React15.createElement("div", { className: "w-full flex flex-col pl-2 pr-2 gap-1" }, ["ALL", "CREDIT", "DEBIT"].map((option) => /* @__PURE__ */ React15.createElement(
@@ -1531,7 +1490,7 @@ var UniversalHomeView = ({
1531
1490
  ThreeDActionButton,
1532
1491
  {
1533
1492
  onClick: primaryAction.onClick,
1534
- className: "px-6 py-2.5 sm:px-8 sm:py-2.5"
1493
+ className: "px-6 sm:px-8"
1535
1494
  },
1536
1495
  /* @__PURE__ */ React16.createElement("span", { className: "flex items-center gap-1.5 text-[13px] tracking-wide " }, primaryAction.label, primaryAction.icon && /* @__PURE__ */ React16.createElement(HugeiconsIcon10, { icon: primaryAction.icon, size: 16 }))
1537
1496
  ), secondaryAction && /* @__PURE__ */ React16.createElement(
@@ -1649,14 +1608,14 @@ var UniversalWalletPage = ({
1649
1608
  {
1650
1609
  onClick: () => onDownloadPayId && onDownloadPayId(selectedWallet),
1651
1610
  isLoading: isGeneratingStatement,
1652
- className: "w-full py-3 text-[13px]"
1611
+ className: "w-full"
1653
1612
  },
1654
1613
  "Generate Statement"
1655
1614
  ), /* @__PURE__ */ React17.createElement(
1656
1615
  "button",
1657
1616
  {
1658
1617
  onClick: () => handleCopy(selectedWallet),
1659
- className: "w-full flex items-center justify-center py-2.5 rounded-full border border-neutral-200 text-black hover:bg-neutral-50 outline-none text-[13px] tracking-wide transition-colors"
1618
+ className: "w-full flex items-center justify-center py-2.5 rounded-full border border-neutral-200 text-black hover:bg-neutral-50 outline-none text-xs tracking-wide transition-colors"
1660
1619
  },
1661
1620
  "Copy Wallet Address"
1662
1621
  )))))));
@@ -2849,7 +2808,15 @@ var UniversalSecurityPage = ({
2849
2808
  toggleLoading: isPasskeyLoading,
2850
2809
  isLast: true
2851
2810
  }
2852
- ))), show2FASetupModal && /* @__PURE__ */ React27.createElement("div", { className: "fixed inset-0 z-120 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ React27.createElement("div", { className: "absolute inset-0 bg-black/40 ", onClick: () => !isSubmitting && setShow2FASetupModal(false) }), /* @__PURE__ */ React27.createElement("div", { className: "relative w-full max-w-sm bg-white rounded-2xl flex flex-col overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200 max-h-[90vh]" }, /* @__PURE__ */ React27.createElement("div", { className: "flex items-center justify-between p-5 shrink-0 " }, /* @__PURE__ */ React27.createElement("h3", { className: "text-[15px] text-black tracking-tight" }, "Enable 2FA"), /* @__PURE__ */ React27.createElement("button", { onClick: () => !isSubmitting && setShow2FASetupModal(false), className: "text-neutral-400 hover:text-black transition-colors outline-none" }, /* @__PURE__ */ React27.createElement(HugeiconsIcon19, { icon: CancelCircleIcon6, size: 18 }))), /* @__PURE__ */ React27.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 pt-2" }, /* @__PURE__ */ React27.createElement("div", { className: "w-full flex justify-center mb-6 mix-blend-multiply" }, twoFaQr ? /* @__PURE__ */ React27.createElement("img", { src: twoFaQr, alt: "2FA QR Code", className: "w-40 h-40 object-contain rounded-xl border border-neutral-100 p-2" }) : /* @__PURE__ */ React27.createElement("div", { className: "w-40 h-40 bg-neutral-100 rounded-xl flex items-center justify-center animate-pulse" })), /* @__PURE__ */ React27.createElement("div", { className: "text-center mb-8 mt-2" }, /* @__PURE__ */ React27.createElement("h2", { className: "text-xl text-black mb-2 tracking-tight" }, "Security Check"), /* @__PURE__ */ React27.createElement("p", { className: "text-[13px] text-neutral-500" }, "Enter the 6-digit code from your app")), /* @__PURE__ */ React27.createElement("form", { className: "space-y-4", autoComplete: "off", onSubmit: (e) => {
2811
+ ))), show2FASetupModal && /* @__PURE__ */ React27.createElement("div", { className: "fixed inset-0 z-120 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ React27.createElement("div", { className: "absolute inset-0 bg-black/40 ", onClick: () => !isSubmitting && setShow2FASetupModal(false) }), /* @__PURE__ */ React27.createElement("div", { className: "relative w-full max-w-sm bg-white rounded-2xl flex flex-col overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200 max-h-[90vh]" }, /* @__PURE__ */ React27.createElement("div", { className: "flex items-center justify-between p-5 shrink-0 " }, /* @__PURE__ */ React27.createElement("h3", { className: "text-[15px] text-black tracking-tight" }, "Enable 2FA"), /* @__PURE__ */ React27.createElement("button", { onClick: () => !isSubmitting && setShow2FASetupModal(false), className: "text-neutral-400 hover:text-black transition-colors outline-none" }, /* @__PURE__ */ React27.createElement(HugeiconsIcon19, { icon: CancelCircleIcon6, size: 18 }))), /* @__PURE__ */ React27.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 pt-2" }, /* @__PURE__ */ React27.createElement("div", { className: "w-full flex justify-center mb-6 mix-blend-multiply" }, twoFaQr ? /* @__PURE__ */ React27.createElement("img", { src: twoFaQr, alt: "2FA QR Code", className: "w-40 h-40 object-contain rounded-xl border border-neutral-100 p-2" }) : /* @__PURE__ */ React27.createElement("div", { className: "w-40 h-40 bg-neutral-100 rounded-xl flex items-center justify-center animate-pulse" })), /* @__PURE__ */ React27.createElement("div", { className: "grid grid-cols-1 gap-y-6 gap-x-4 mb-8" }, /* @__PURE__ */ React27.createElement("div", null, /* @__PURE__ */ React27.createElement("span", { className: "text-[11px] tracking-[0.2em] text-neutral-400 block mb-2 uppercase" }, "Setup Key"), /* @__PURE__ */ React27.createElement("div", { className: "flex items-center gap-2 min-w-0 bg-neutral-50 px-3 py-2.5 rounded-xl " }, /* @__PURE__ */ React27.createElement("span", { className: "text-[13px] font-mono tracking-widest text-black truncate min-w-0 block flex-1" }, twoFaSecret), /* @__PURE__ */ React27.createElement(
2812
+ "button",
2813
+ {
2814
+ type: "button",
2815
+ onClick: () => handleCopySecret(twoFaSecret),
2816
+ className: "text-neutral-400 hover:text-black transition-colors outline-none shrink-0 ml-2"
2817
+ },
2818
+ /* @__PURE__ */ React27.createElement(HugeiconsIcon19, { icon: Copy01Icon3, size: 16 })
2819
+ )))), /* @__PURE__ */ React27.createElement("div", { className: "text-center mb-8 mt-2" }, /* @__PURE__ */ React27.createElement("h2", { className: "text-xl text-black mb-2 tracking-tight" }, "Security Check"), /* @__PURE__ */ React27.createElement("p", { className: "text-[13px] text-neutral-500" }, "Enter the 6-digit code from your app")), /* @__PURE__ */ React27.createElement("form", { className: "space-y-4", autoComplete: "off", onSubmit: (e) => {
2853
2820
  e.preventDefault();
2854
2821
  submitEnable2FA(otp.join(""));
2855
2822
  } }, /* @__PURE__ */ React27.createElement("div", { className: "flex justify-between gap-2 pb-6", onPaste: handlePaste }, otp.map((digit, index) => /* @__PURE__ */ React27.createElement(
@@ -2885,7 +2852,7 @@ var UniversalSecurityPage = ({
2885
2852
  {
2886
2853
  type: "button",
2887
2854
  onClick: () => handleCopySecret(twoFaSecret),
2888
- className: "w-full flex items-center justify-center py-3 rounded-full bg-neutral-100 text-black hover:bg-neutral-200 outline-none text-[13px] font-medium tracking-wide transition-colors mt-3"
2855
+ className: "w-full flex items-center justify-center py-2.5 rounded-full border border-neutral-200 text-black hover:bg-neutral-50 outline-none text-xs font-medium tracking-wide transition-colors mt-2"
2889
2856
  },
2890
2857
  /* @__PURE__ */ React27.createElement(HugeiconsIcon19, { icon: Copy01Icon3, size: 16, className: "mr-2" }),
2891
2858
  "Copy Secret Key"
@@ -2920,7 +2887,7 @@ var UniversalSecurityPage = ({
2920
2887
  className: "w-full py-3.5"
2921
2888
  },
2922
2889
  "Verify & Disable"
2923
- ))))), showPasskeyModal && /* @__PURE__ */ React27.createElement("div", { className: "fixed inset-0 z-120 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ React27.createElement("div", { className: "absolute inset-0 bg-black/40 ", onClick: () => !isSubmitting && setShowPasskeyModal(false) }), /* @__PURE__ */ React27.createElement("div", { className: "relative w-full max-w-sm bg-white rounded-2xl flex flex-col overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ React27.createElement("div", { className: "flex items-center justify-between p-5 shrink-0" }, /* @__PURE__ */ React27.createElement("h3", { className: "text-[15px] text-black tracking-tight" }, "Enable Passkey"), /* @__PURE__ */ React27.createElement("button", { onClick: () => !isSubmitting && setShowPasskeyModal(false), className: "text-neutral-400 hover:text-black transition-colors outline-none" }, /* @__PURE__ */ React27.createElement(HugeiconsIcon19, { icon: CancelCircleIcon6, size: 18 }))), /* @__PURE__ */ React27.createElement("div", { className: "p-6 text-center" }, /* @__PURE__ */ React27.createElement("p", { className: "text-[13px] text-neutral-500 mb-8 leading-relaxed" }, "Use your device's biometrics (Face ID, Touch ID, or PIN) to securely sign into your account without needing a password."), /* @__PURE__ */ React27.createElement(
2890
+ ))))), showPasskeyModal && /* @__PURE__ */ React27.createElement("div", { className: "fixed inset-0 z-120 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ React27.createElement("div", { className: "absolute inset-0 bg-black/40 ", onClick: () => !isSubmitting && setShowPasskeyModal(false) }), /* @__PURE__ */ React27.createElement("div", { className: "relative w-full max-w-sm bg-white rounded-2xl flex flex-col overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ React27.createElement("div", { className: "flex items-center justify-between p-5 shrink-0" }, /* @__PURE__ */ React27.createElement("h3", { className: "text-[15px] text-black tracking-tight" }, "Enable Passkey"), /* @__PURE__ */ React27.createElement("button", { onClick: () => !isSubmitting && setShowPasskeyModal(false), className: "text-neutral-400 hover:text-black transition-colors outline-none" }, /* @__PURE__ */ React27.createElement(HugeiconsIcon19, { icon: CancelCircleIcon6, size: 18 }))), /* @__PURE__ */ React27.createElement("div", { className: "p-6 text-center" }, /* @__PURE__ */ React27.createElement("h2", { className: "text-lg text-black mb-2 tracking-tight" }, "Simplify your Sign In"), /* @__PURE__ */ React27.createElement("p", { className: "text-[13px] text-neutral-500 mb-8 leading-relaxed" }, "Use your device's biometrics (Face ID, Touch ID, or PIN) to securely sign into your account without needing a password."), /* @__PURE__ */ React27.createElement(
2924
2891
  ThreeDActionButton,
2925
2892
  {
2926
2893
  onClick: submitEnablePasskey,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@retinalabsllc/zairusjs",
3
- "version": "11.0.1",
3
+ "version": "11.0.5",
4
4
  "description": "A perceptive, Ai data driven Next.js UI component library.",
5
5
  "author": "Retina Labs Company",
6
6
  "license": "MIT",