Authentication Flow
React Component Example
import { useState, useEffect } from "react";
import { YieldFiSDK, AuthenticationError, NetworkError } from "yieldfi-sdk";
import { ethers } from "ethers";
function AuthExample() {
const [sdk, setSdk] = useState<YieldFiSDK | null>(null);
const [user, setUser] = useState<any>(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
initializeSDK();
checkExistingAuth();
}, []);
const initializeSDK = async () => {
try {
const sdkInstance = await YieldFiSDK.create({
gatewayUrl: "https://gw.yield.fi",
});
setSdk(sdkInstance);
} catch (err: any) {
setError(`Failed to initialize SDK: ${err.message}`);
}
};
const checkExistingAuth = async () => {
const accessToken = localStorage.getItem("accessToken");
if (!accessToken || !sdk) return;
try {
// Verify token is still valid by making a test request
const transactions = await sdk.vault.getTransactions(
{ chainId: 1, page: 1, pageSize: 1 },
accessToken
);
// Token is valid, load user info
const userStr = localStorage.getItem("user");
if (userStr) {
setUser(JSON.parse(userStr));
}
} catch (err) {
// Token expired or invalid, clear storage
localStorage.removeItem("accessToken");
localStorage.removeItem("refreshToken");
localStorage.removeItem("user");
}
};
const handleLogin = async () => {
if (!sdk) {
setError("SDK not initialized");
return;
}
try {
setLoading(true);
setError(null);
// 1. Connect to wallet
if (!window.ethereum) {
throw new Error("MetaMask not installed");
}
const provider = new ethers.BrowserProvider(window.ethereum);
await provider.send("eth_requestAccounts", []);
const signer = await provider.getSigner();
const address = await signer.getAddress();
// 2. Generate nonce
const nonce = await sdk.auth.generateNonce({ address });
// 3. Sign message
const signature = await signer.signMessage(nonce.message);
// 4. Login
const authResponse = await sdk.auth.login({
address,
signature,
message: nonce.message,
});
// 5. Store tokens and user info
localStorage.setItem("accessToken", authResponse.accessToken);
localStorage.setItem("refreshToken", authResponse.refreshToken);
localStorage.setItem("user", JSON.stringify(authResponse.user));
setUser(authResponse.user);
console.log("Login successful!");
} catch (err: any) {
if (err instanceof AuthenticationError) {
setError(`Authentication failed: ${err.message}`);
} else if (err instanceof NetworkError) {
setError(`Network error: ${err.message}`);
} else {
setError(`Login failed: ${err.message}`);
}
} finally {
setLoading(false);
}
};
const handleLogout = async () => {
if (!sdk) return;
try {
const accessToken = localStorage.getItem("accessToken");
if (accessToken) {
await sdk.auth.logout(accessToken);
}
} catch (err) {
console.error("Logout error:", err);
} finally {
localStorage.removeItem("accessToken");
localStorage.removeItem("refreshToken");
localStorage.removeItem("user");
setUser(null);
}
};
if (!sdk) {
return <div>Initializing SDK...</div>;
}
return (
<div>
{user ? (
<div>
<p>Logged in as: {user.address}</p>
<p>Role: {user.role}</p>
<button onClick={handleLogout}>Logout</button>
</div>
) : (
<div>
<button onClick={handleLogin} disabled={loading}>
{loading ? "Connecting..." : "Connect Wallet"}
</button>
{error && <p style={{ color: "red" }}>{error}</p>}
</div>
)}
</div>
);
}
export default AuthExample;Token Refresh Utility
Usage in API Calls
Last updated