decane-connect-kit 2.2.4 → 2.2.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.cts CHANGED
@@ -752,6 +752,9 @@ interface SocialWalletModalProps {
752
752
  authMethods?: Array<"google" | "email">;
753
753
  customAuthLabel?: string;
754
754
  onCustomAuthSignIn?: () => Promise<void>;
755
+ canUsePasskey?: boolean;
756
+ passkeyAddress?: string | null;
757
+ onPasskeySignIn?: () => Promise<unknown>;
755
758
  onRotateShares: (opts: {
756
759
  password: string;
757
760
  passwordHint?: string;
@@ -763,7 +766,7 @@ interface SocialWalletModalProps {
763
766
  rpcUrls?: Record<string, string>;
764
767
  chains?: string[];
765
768
  }
766
- declare function SocialWalletModal({ open, onClose, theme, socialAuth, onUnlock, onDisconnect, onGoogleSignIn, onEmailStart, onEmailVerify, authMethods, customAuthLabel, onCustomAuthSignIn, onRotateShares, onExportPortableBackup, rpcUrls, chains, }: SocialWalletModalProps): React.ReactPortal | null;
769
+ declare function SocialWalletModal({ open, onClose, theme, socialAuth, onUnlock, onDisconnect, onGoogleSignIn, onEmailStart, onEmailVerify, authMethods, customAuthLabel, onCustomAuthSignIn, canUsePasskey, passkeyAddress, onPasskeySignIn, onRotateShares, onExportPortableBackup, rpcUrls, chains, }: SocialWalletModalProps): React.ReactPortal | null;
767
770
 
768
771
  declare function DecaneMark({ size, muted }: {
769
772
  size?: number;
@@ -787,6 +790,7 @@ declare function useSocialAuth(): {
787
790
  solana?: string;
788
791
  } | null;
789
792
  sessionExpiresAt: number | null;
793
+ canUsePasskey: boolean;
790
794
  needsReconnect: boolean;
791
795
  googleLoading: boolean;
792
796
  emailLoading: boolean;
@@ -804,6 +808,7 @@ declare function useSocialAuth(): {
804
808
  providerId?: string;
805
809
  }) => Promise<void>;
806
810
  signInWithCustomAuth: (() => Promise<void>) | undefined;
811
+ signInWithPasskey: () => Promise<void>;
807
812
  unlock: () => Promise<void>;
808
813
  disconnect: () => Promise<void>;
809
814
  };
package/dist/index.d.ts CHANGED
@@ -752,6 +752,9 @@ interface SocialWalletModalProps {
752
752
  authMethods?: Array<"google" | "email">;
753
753
  customAuthLabel?: string;
754
754
  onCustomAuthSignIn?: () => Promise<void>;
755
+ canUsePasskey?: boolean;
756
+ passkeyAddress?: string | null;
757
+ onPasskeySignIn?: () => Promise<unknown>;
755
758
  onRotateShares: (opts: {
756
759
  password: string;
757
760
  passwordHint?: string;
@@ -763,7 +766,7 @@ interface SocialWalletModalProps {
763
766
  rpcUrls?: Record<string, string>;
764
767
  chains?: string[];
765
768
  }
766
- declare function SocialWalletModal({ open, onClose, theme, socialAuth, onUnlock, onDisconnect, onGoogleSignIn, onEmailStart, onEmailVerify, authMethods, customAuthLabel, onCustomAuthSignIn, onRotateShares, onExportPortableBackup, rpcUrls, chains, }: SocialWalletModalProps): React.ReactPortal | null;
769
+ declare function SocialWalletModal({ open, onClose, theme, socialAuth, onUnlock, onDisconnect, onGoogleSignIn, onEmailStart, onEmailVerify, authMethods, customAuthLabel, onCustomAuthSignIn, canUsePasskey, passkeyAddress, onPasskeySignIn, onRotateShares, onExportPortableBackup, rpcUrls, chains, }: SocialWalletModalProps): React.ReactPortal | null;
767
770
 
768
771
  declare function DecaneMark({ size, muted }: {
769
772
  size?: number;
@@ -787,6 +790,7 @@ declare function useSocialAuth(): {
787
790
  solana?: string;
788
791
  } | null;
789
792
  sessionExpiresAt: number | null;
793
+ canUsePasskey: boolean;
790
794
  needsReconnect: boolean;
791
795
  googleLoading: boolean;
792
796
  emailLoading: boolean;
@@ -804,6 +808,7 @@ declare function useSocialAuth(): {
804
808
  providerId?: string;
805
809
  }) => Promise<void>;
806
810
  signInWithCustomAuth: (() => Promise<void>) | undefined;
811
+ signInWithPasskey: () => Promise<void>;
807
812
  unlock: () => Promise<void>;
808
813
  disconnect: () => Promise<void>;
809
814
  };
package/dist/index.js CHANGED
@@ -4817,7 +4817,10 @@ function SignInView({
4817
4817
  authMethods,
4818
4818
  resumeHint,
4819
4819
  customAuthLabel,
4820
- onCustomAuthSignIn
4820
+ onCustomAuthSignIn,
4821
+ canUsePasskey,
4822
+ passkeyAddress,
4823
+ onPasskeySignIn
4821
4824
  }) {
4822
4825
  const [googleLoading, setGoogleLoading] = useState2(false);
4823
4826
  const [email, setEmail] = useState2("");
@@ -4825,7 +4828,25 @@ function SignInView({
4825
4828
  const [emailSent, setEmailSent] = useState2(false);
4826
4829
  const [emailLoading, setEmailLoading] = useState2(false);
4827
4830
  const [customLoading, setCustomLoading] = useState2(false);
4831
+ const [passkeyLoading, setPasskeyLoading] = useState2(false);
4832
+ const [showOtherMethods, setShowOtherMethods] = useState2(false);
4828
4833
  const [error, setError] = useState2("");
4834
+ const passkeyFirst = !!canUsePasskey && !!onPasskeySignIn && !showOtherMethods;
4835
+ async function handlePasskey() {
4836
+ if (!onPasskeySignIn) return;
4837
+ setError("");
4838
+ setPasskeyLoading(true);
4839
+ try {
4840
+ await onPasskeySignIn();
4841
+ } catch (e) {
4842
+ const err = e;
4843
+ if (err?.name !== "UserCancelledError") {
4844
+ setError(err?.message ?? "Passkey sign-in failed");
4845
+ setShowOtherMethods(true);
4846
+ }
4847
+ setPasskeyLoading(false);
4848
+ }
4849
+ }
4829
4850
  async function handleGoogle() {
4830
4851
  setError("");
4831
4852
  setGoogleLoading(true);
@@ -4885,7 +4906,47 @@ function SignInView({
4885
4906
  fontFamily: "inherit",
4886
4907
  boxSizing: "border-box"
4887
4908
  };
4888
- return /* @__PURE__ */ React3.createElement("div", { style: { padding: "0 16px 16px" } }, resumeHint && /* @__PURE__ */ React3.createElement("div", { style: { fontSize: 12, color: "var(--dc-text-muted)", marginBottom: 12, textAlign: "center" } }, "Welcome back \u2014 sign in again to resume ", resumeHint), authMethods.includes("google") && /* @__PURE__ */ React3.createElement(
4909
+ return /* @__PURE__ */ React3.createElement("div", { style: { padding: "0 16px 16px" } }, resumeHint && !passkeyFirst && /* @__PURE__ */ React3.createElement("div", { style: { fontSize: 12, color: "var(--dc-text-muted)", marginBottom: 12, textAlign: "center" } }, "Welcome back \u2014 sign in again to resume ", resumeHint), passkeyFirst && /* @__PURE__ */ React3.createElement("div", null, /* @__PURE__ */ React3.createElement("div", { style: { fontSize: 12, color: "var(--dc-text-muted)", marginBottom: 12, textAlign: "center" } }, "Welcome back \u2014 unlock to resume", passkeyAddress ? ` ${passkeyAddress.slice(0, 6)}\u2026${passkeyAddress.slice(-4)}` : ""), /* @__PURE__ */ React3.createElement(
4910
+ "button",
4911
+ {
4912
+ onClick: handlePasskey,
4913
+ disabled: passkeyLoading,
4914
+ style: {
4915
+ width: "100%",
4916
+ padding: "11px 0",
4917
+ background: "var(--dc-accent)",
4918
+ color: "var(--dc-accent-text)",
4919
+ border: "none",
4920
+ borderRadius: 10,
4921
+ fontSize: 13,
4922
+ fontWeight: 700,
4923
+ cursor: passkeyLoading ? "not-allowed" : "pointer",
4924
+ opacity: passkeyLoading ? 0.7 : 1,
4925
+ fontFamily: "inherit",
4926
+ display: "flex",
4927
+ alignItems: "center",
4928
+ justifyContent: "center",
4929
+ gap: 7
4930
+ }
4931
+ },
4932
+ passkeyLoading ? "Verifying\u2026" : "\u{1F513} Continue with passkey"
4933
+ ), /* @__PURE__ */ React3.createElement(
4934
+ "button",
4935
+ {
4936
+ onClick: () => setShowOtherMethods(true),
4937
+ style: {
4938
+ width: "100%",
4939
+ marginTop: 10,
4940
+ background: "none",
4941
+ border: "none",
4942
+ color: "var(--dc-text-muted)",
4943
+ fontSize: 12,
4944
+ cursor: "pointer",
4945
+ fontFamily: "inherit"
4946
+ }
4947
+ },
4948
+ "Use email or Google instead"
4949
+ ), error && /* @__PURE__ */ React3.createElement("div", { style: { marginTop: 10, fontSize: 12, color: "var(--dc-danger, #ff5533)" } }, error)), !passkeyFirst && authMethods.includes("google") && /* @__PURE__ */ React3.createElement(
4889
4950
  "button",
4890
4951
  {
4891
4952
  onClick: handleGoogle,
@@ -4906,7 +4967,7 @@ function SignInView({
4906
4967
  }
4907
4968
  },
4908
4969
  googleLoading ? "Redirecting\u2026" : "Continue with Google"
4909
- ), authMethods.includes("email") && /* @__PURE__ */ React3.createElement(React3.Fragment, null, authMethods.includes("google") && /* @__PURE__ */ React3.createElement("div", { style: { textAlign: "center", color: "var(--dc-text-muted)", fontSize: 12, margin: "10px 0" } }, "\u2014 or \u2014"), !emailSent ? /* @__PURE__ */ React3.createElement("form", { onSubmit: handleEmailStart, style: { display: "flex", gap: 8 } }, /* @__PURE__ */ React3.createElement(
4970
+ ), !passkeyFirst && authMethods.includes("email") && /* @__PURE__ */ React3.createElement(React3.Fragment, null, authMethods.includes("google") && /* @__PURE__ */ React3.createElement("div", { style: { textAlign: "center", color: "var(--dc-text-muted)", fontSize: 12, margin: "10px 0" } }, "\u2014 or \u2014"), !emailSent ? /* @__PURE__ */ React3.createElement("form", { onSubmit: handleEmailStart, style: { display: "flex", gap: 8 } }, /* @__PURE__ */ React3.createElement(
4910
4971
  "input",
4911
4972
  {
4912
4973
  type: "email",
@@ -4945,7 +5006,7 @@ function SignInView({
4945
5006
  fontWeight: 700,
4946
5007
  cursor: "pointer",
4947
5008
  fontFamily: "inherit"
4948
- } }, emailLoading ? "\u2026" : "Verify"))), customAuthLabel && onCustomAuthSignIn && /* @__PURE__ */ React3.createElement(React3.Fragment, null, (authMethods.includes("google") || authMethods.includes("email")) && /* @__PURE__ */ React3.createElement("div", { style: { textAlign: "center", color: "var(--dc-text-muted)", fontSize: 12, margin: "10px 0" } }, "\u2014 or \u2014"), /* @__PURE__ */ React3.createElement(
5009
+ } }, emailLoading ? "\u2026" : "Verify"))), !passkeyFirst && customAuthLabel && onCustomAuthSignIn && /* @__PURE__ */ React3.createElement(React3.Fragment, null, (authMethods.includes("google") || authMethods.includes("email")) && /* @__PURE__ */ React3.createElement("div", { style: { textAlign: "center", color: "var(--dc-text-muted)", fontSize: 12, margin: "10px 0" } }, "\u2014 or \u2014"), /* @__PURE__ */ React3.createElement(
4949
5010
  "button",
4950
5011
  {
4951
5012
  onClick: handleCustomAuth,
@@ -5084,6 +5145,9 @@ function SocialWalletModal({
5084
5145
  authMethods = ["google", "email"],
5085
5146
  customAuthLabel,
5086
5147
  onCustomAuthSignIn,
5148
+ canUsePasskey,
5149
+ passkeyAddress,
5150
+ onPasskeySignIn,
5087
5151
  onRotateShares,
5088
5152
  onExportPortableBackup,
5089
5153
  rpcUrls,
@@ -5214,7 +5278,10 @@ function SocialWalletModal({
5214
5278
  authMethods,
5215
5279
  resumeHint: socialAuth.needsReconnect ? "your wallet" : void 0,
5216
5280
  customAuthLabel,
5217
- onCustomAuthSignIn
5281
+ onCustomAuthSignIn,
5282
+ canUsePasskey,
5283
+ passkeyAddress,
5284
+ onPasskeySignIn
5218
5285
  }
5219
5286
  ) : /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement("div", { style: {
5220
5287
  margin: "0 16px 14px",
@@ -5609,6 +5676,9 @@ function DecaneKit({ config, children }) {
5609
5676
  onEmailStart: connectWithEmail,
5610
5677
  onEmailVerify: verifyEmailCode2,
5611
5678
  authMethods: config?.social?.authMethods ?? ["google", "email"],
5679
+ canUsePasskey: socialAuth.canUsePasskey,
5680
+ passkeyAddress: socialAuth.addresses?.evm ?? socialAuth.addresses?.solana ?? null,
5681
+ onPasskeySignIn: signInWithPasskey,
5612
5682
  onRotateShares: socialRotateShares,
5613
5683
  onExportPortableBackup: socialExportPortableBackup,
5614
5684
  rpcUrls: config?.social?.rpcUrls,
@@ -5638,6 +5708,7 @@ function useSocialAuth() {
5638
5708
  connectWithToken,
5639
5709
  customAuthLabel,
5640
5710
  connectWithCustomAuth,
5711
+ signInWithPasskey: ctxSignInWithPasskey,
5641
5712
  socialUnlock,
5642
5713
  socialDisconnect
5643
5714
  } = useDecaneContext();
@@ -5706,6 +5777,15 @@ function useSocialAuth() {
5706
5777
  setCustomLoading(false);
5707
5778
  }
5708
5779
  }, [connectWithCustomAuth]);
5780
+ const signInWithPasskey = useCallback4(async () => {
5781
+ setError(null);
5782
+ try {
5783
+ await ctxSignInWithPasskey();
5784
+ } catch (e) {
5785
+ setError(e.message);
5786
+ throw e;
5787
+ }
5788
+ }, [ctxSignInWithPasskey]);
5709
5789
  const unlock = useCallback4(async () => {
5710
5790
  setError(null);
5711
5791
  try {
@@ -5730,6 +5810,8 @@ function useSocialAuth() {
5730
5810
  isNewUser: socialAuth.isNewUser,
5731
5811
  addresses: socialAuth.addresses,
5732
5812
  sessionExpiresAt: socialAuth.sessionExpiresAt,
5813
+ // True when this device can skip the full sign-in and resume with a passkey.
5814
+ canUsePasskey: socialAuth.canUsePasskey,
5733
5815
  // True when addresses are known (from a previous visit) but there's no
5734
5816
  // live session — unlock() will always throw in this state (every
5735
5817
  // unlock requires a fresh JWT, and JWTs are never persisted). Route
@@ -5747,6 +5829,7 @@ function useSocialAuth() {
5747
5829
  confirmEmailCode,
5748
5830
  signInWithToken,
5749
5831
  signInWithCustomAuth: connectWithCustomAuth ? signInWithCustomAuth : void 0,
5832
+ signInWithPasskey,
5750
5833
  unlock,
5751
5834
  disconnect
5752
5835
  };