@enclavemoney/enclave-wallet-sdk
Version:
A simple enclave wallet SDK for React applications
222 lines (196 loc) • 5.79 kB
text/typescript
import {
signInWithPopup,
signOut,
User,
UserCredential,
signInWithCustomToken,
} from "firebase/auth";
import { auth, googleProvider, twitterProvider } from "../config/firebase";
import { getSocialAccount, SocialLoginResponse } from "./services";
export interface GoogleAuthResult {
success: boolean;
user?: SocialLoginResponse;
error?: string;
}
/**
* Sign in with custom token and get Firebase ID token and refresh token
*/
export const signInWithCustomTokenAndGetIdToken = async (
customToken: string
): Promise<{
success: boolean;
idToken?: string;
refreshToken?: string;
error?: string;
}> => {
try {
const userCredential = await signInWithCustomToken(auth, customToken);
const user = userCredential.user;
// Get the ID token for API calls
const idToken = await user.getIdToken();
// Get the refresh token
const refreshToken = user.refreshToken;
return {
success: true,
idToken,
refreshToken,
};
} catch (error: any) {
console.error("Error signing in with custom token:", error);
let errorMessage = "Failed to sign in with custom token";
// Handle specific Firebase Auth errors
switch (error.code) {
case "auth/invalid-custom-token":
errorMessage = "Invalid custom token";
break;
case "auth/custom-token-mismatch":
errorMessage = "Custom token mismatch";
break;
case "auth/network-request-failed":
errorMessage = "Network error. Please check your connection";
break;
default:
errorMessage = error.message || "Failed to sign in with custom token";
}
return {
success: false,
error: errorMessage,
};
}
};
/**
* Sign in with Google using Firebase Auth
*/
export const signInWithGoogle = async (
apiKey: string
): Promise<GoogleAuthResult> => {
try {
const result: UserCredential = await signInWithPopup(auth, googleProvider);
const user = result.user;
// Call the social account API with the Google user data
const socialAccountResult = await getSocialAccount(
{ googleUser: user },
apiKey
);
console.log("socialAccountResult >>>>>", user);
return {
success: true,
// @ts-ignore
user: {
...socialAccountResult,
// @ts-ignore
accessToken: result.user.accessToken,
refreshToken: result.user.refreshToken,
},
};
} catch (error: any) {
console.error("Error signing in with Google:", error);
let errorMessage = "Failed to sign in with Google";
// Handle specific Firebase Auth errors
switch (error.code) {
case "auth/popup-closed-by-user":
errorMessage = "Sign-in cancelled by user";
break;
case "auth/popup-blocked":
errorMessage = "Popup was blocked. Please allow popups for this site";
break;
case "auth/cancelled-popup-request":
errorMessage = "Sign-in request was cancelled";
break;
case "auth/network-request-failed":
errorMessage = "Network error. Please check your connection";
break;
default:
errorMessage = error.message || "Failed to sign in with Google";
}
return {
success: false,
error: errorMessage,
};
}
};
export interface TwitterAuthResult {
success: boolean;
user?: SocialLoginResponse;
error?: string;
}
/**
* Sign in with Twitter (X) using Firebase Auth
*/
export const signInWithX = async (
apiKey: string
): Promise<TwitterAuthResult> => {
try {
const result: UserCredential = await signInWithPopup(auth, twitterProvider);
const user = result.user;
// Construct the twitterUser object as required
const twitterUser = {
uid: user.uid,
// @ts-ignore
username: user.reloadUserInfo?.providerUserInfo?.[0]?.screenName || "",
name: user.displayName || undefined,
profile_image_url: user.photoURL || undefined,
email: user.email || undefined,
};
// Call the social account API with the Twitter user data
const socialAccountResult = await getSocialAccount({ twitterUser }, apiKey);
return {
success: true,
// @ts-ignore
user: {
...socialAccountResult,
// @ts-ignore
accessToken: result.user.accessToken,
refreshToken: result.user.refreshToken,
},
};
} catch (error: any) {
console.error("Error signing in with Twitter/X:", error);
let errorMessage = "Failed to sign in with Twitter/X";
// Handle specific Firebase Auth errors
switch (error.code) {
case "auth/popup-closed-by-user":
errorMessage = "Sign-in cancelled by user";
break;
case "auth/popup-blocked":
errorMessage = "Popup was blocked. Please allow popups for this site";
break;
case "auth/cancelled-popup-request":
errorMessage = "Sign-in request was cancelled";
break;
case "auth/network-request-failed":
errorMessage = "Network error. Please check your connection";
break;
default:
errorMessage = error.message || "Failed to sign in with Twitter/X";
}
return {
success: false,
error: errorMessage,
};
}
};
/**
* Sign out the current user
*/
export const signOutUser = async (): Promise<boolean> => {
try {
await signOut(auth);
return true;
} catch (error) {
console.error("Error signing out:", error);
return false;
}
};
/**
* Get the current authenticated user
*/
export const getCurrentUser = (): User | null => {
return auth.currentUser;
};
/**
* Listen to authentication state changes
*/
export const onAuthStateChange = (callback: (user: User | null) => void) => {
return auth.onAuthStateChanged(callback);
};