Social Login Flow
Implement social login with OAuth redirect flows, email OTP, phone OTP, and custom JWT
Social Login Flow
React Implementation
The useNeroConnect hook provides the simplest way to add social login in React:
import { useNeroConnect } from "@nerochain/mpc-sdk/react";
function LoginButton() {
const { connect, handleCallback, isConnecting, error } = useNeroConnect();
return (
<div>
<button
onClick={() => connect("google")}
disabled={isConnecting}
>
{isConnecting ? "Connecting..." : "Login with Google"}
</button>
{error && <p>{error.message}</p>}
</div>
);
}Available useNeroConnect Methods
| Method | Purpose |
|---|---|
connect(provider, redirectUri?) | Initiates OAuth flow for a provider |
handleCallback(provider, code, state, redirectUri?) | Processes the OAuth redirect |
loginWithEmail(email, type?) | Starts email OTP or magic link flow |
verifyEmailLogin(email, code) | Completes email verification |
loginWithPhone(phoneNumber) | Initiates SMS OTP |
verifyPhoneLogin(phoneNumber, code) | Completes phone verification |
loginWithCustomJwt(options) | Authenticates with an external JWT |
isConnecting | Boolean indicating active authentication |
error | Contains the last authentication error |
Email OTP Flow
function EmailLogin() {
const { loginWithEmail, verifyEmailLogin, isConnecting } = useNeroConnect();
const [step, setStep] = useState<"email" | "code">("email");
const [email, setEmail] = useState("");
const [code, setCode] = useState("");
const handleSendOTP = async () => {
await loginWithEmail(email);
setStep("code");
};
const handleVerify = async () => {
await verifyEmailLogin(email, code);
};
if (step === "email") {
return (
<div>
<input value={email} onChange={(e) => setEmail(e.target.value)} placeholder="Email" />
<button onClick={handleSendOTP} disabled={isConnecting}>Send Code</button>
</div>
);
}
return (
<div>
<input value={code} onChange={(e) => setCode(e.target.value)} placeholder="Verification Code" />
<button onClick={handleVerify} disabled={isConnecting}>Verify</button>
</div>
);
}Phone OTP Flow
function PhoneLogin() {
const { loginWithPhone, verifyPhoneLogin, isConnecting } = useNeroConnect();
const [phone, setPhone] = useState("");
const [code, setCode] = useState("");
const [otpSent, setOtpSent] = useState(false);
const handleSend = async () => {
await loginWithPhone(phone);
setOtpSent(true);
};
const handleVerify = async () => {
await verifyPhoneLogin(phone, code);
};
if (!otpSent) {
return (
<div>
<input value={phone} onChange={(e) => setPhone(e.target.value)} placeholder="+1234567890" />
<button onClick={handleSend} disabled={isConnecting}>Send OTP</button>
</div>
);
}
return (
<div>
<input value={code} onChange={(e) => setCode(e.target.value)} placeholder="OTP Code" />
<button onClick={handleVerify} disabled={isConnecting}>Verify</button>
</div>
);
}Vanilla JS Implementation
Use the core SDK directly for non-React applications:
import { NeroMpcSDK } from "@nerochain/mpc-sdk";
const sdk = new NeroMpcSDK({
backendUrl: "https://your-backend.example.com",
chainId: 689,
});
await sdk.init();OAuth Redirect Flow
await sdk.loginWithGoogle();After the provider redirects back to your application, handle the callback:
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get("code");
const state = urlParams.get("state");
if (code && state) {
const result = await sdk.handleOAuthCallback({
provider: "google",
code,
state,
});
if (result.requiresDKG) {
await sdk.generateWallet();
}
}Email OTP (Vanilla JS)
await sdk.loginWithEmail("user@example.com");
const result = await sdk.verifyEmailLogin("user@example.com", "123456");Custom JWT
await sdk.loginWithCustomJwt({
verifierId: "your-verifier-id",
idToken: "your-existing-jwt-token",
});Post-Login: Wallet Generation
After authentication, check the requiresDKG flag. When true, the user has no stored key material on the backend (typically on first login) and you must call generateWallet():
const result = await sdk.handleOAuthCallback({ provider, code, state });
if (result.requiresDKG) {
const wallet = await sdk.generateWallet();
console.log("Wallet address:", wallet.eoaAddress);
}Handling the Redirect
After OAuth authentication, the provider redirects back to your application with code and state query parameters. Ensure your OAuth redirect URI is registered with the provider and points back to your application URL.
The handleOAuthCallback() method:
- Collects a device fingerprint from
navigator.userAgent - Exchanges the authorization code via
POST /api/v2/auth/social-login - Encrypts and stores access/refresh tokens
- Initializes
ClientKeyManagerfor key share storage - Emits the
"login"event with user profile data
Pre-built Modal
For a complete login UI with all providers preconfigured, use the modal component:
import { NeroMpcAuthProvider } from "@nerochain/mpc-sdk/react";
import { LoginButton } from "@nerochain/mpc-sdk/modal";
function App() {
return (
<NeroMpcAuthProvider config={{ backendUrl: "https://your-backend.example.com", chainId: 689 }}>
<LoginButton />
</NeroMpcAuthProvider>
);
}The modal displays all configured providers and handles the full authentication flow including redirect handling.