useAuth
The useAuth hook handles Sign-In with Ethereum (SIWE) authentication for Silent Swap. It manages the full authentication flow including nonce generation, message signing, and auth caching.
Import
import { useAuth, useSilentClient } from '@silentswap/react';
import { useAccount, useWalletClient } from 'wagmi';Basic Usage
import { useAuth, useSilentClient } from '@silentswap/react';
import { useAccount, useWalletClient } from 'wagmi';
import { ENVIRONMENT } from '@silentswap/sdk';
function AuthComponent() {
const { address } = useAccount();
const { data: walletClient } = useWalletClient();
const { client } = useSilentClient({
config: {
environment: ENVIRONMENT.MAINNET,
},
});
const {
auth,
isAuthenticated,
signIn,
signOut,
isLoading,
error,
} = useAuth({
client,
address: address!,
walletClient: walletClient as any,
domain: 'example.com',
autoAuthenticate: true, // Automatically authenticate when ready
});
if (isLoading) {
return <div>Authenticating...</div>;
}
if (error) {
return <div>Error: {error.message}</div>;
}
if (isAuthenticated()) {
return (
<div>
<p>Authenticated as {auth?.address}</p>
<button onClick={signOut}>Sign Out</button>
</div>
);
}
return (
<button onClick={signIn} disabled={isLoading}>
Sign In with Ethereum
</button>
);
}API Reference
Options
interface useAuthOptions {
/** SilentSwap client instance */
client?: SilentSwapClient;
/** User's EVM address */
address?: `0x${string}`;
/** Wallet client for signing operations */
walletClient?: WalletClient;
/** Wagmi connector */
connector?: Connector;
/** Domain for SIWE message (defaults to window.location.host) */
domain?: string;
/** Whether to auto-authenticate when dependencies are available */
autoAuthenticate?: boolean;
}Return Value
interface useAuthReturn {
// State
auth: AuthResponse | null;
nonce: string | null;
isLoading: boolean;
error: Error | null;
// Sign-in message creation
createSignInMessage: (
address: `0x${string}`,
nonce: string,
domain?: string
) => SignInMessage;
// EIP-712 document creation
createEip712DocForOrder: (
quoteResponse: QuoteResponse
) => ReturnType<typeof createEip712DocForOrder>;
createEip712DocForWalletGeneration: (
scope: string,
token: string
) => ReturnType<typeof createEip712DocForWalletGeneration>;
// Authentication methods
getNonce: () => Promise<string>;
authenticate: () => Promise<AuthResponse | null>;
signIn: () => Promise<AuthResponse | null>;
signOut: () => void;
isAuthenticated: () => boolean;
}Authentication Flow
- Get Nonce - Request a nonce from the server
- Create SIWE Message - Generate the sign-in message
- Sign Message - User signs the message with their wallet
- Authenticate - Send signed message to server
- Cache Auth - Store authentication response locally
Auto-Authentication
Enable automatic authentication when all dependencies are ready:
const { auth, isAuthenticated } = useAuth({
client,
address: address!,
walletClient,
autoAuthenticate: true, // Automatically authenticate
});The hook will:
- Check for cached authentication first
- Automatically authenticate if cache is expired or missing
- Handle errors gracefully
Manual Authentication
You can also manually control the authentication flow:
const {
getNonce,
authenticate,
createSignInMessage,
} = useAuth({
client,
address: address!,
walletClient,
autoAuthenticate: false,
});
const handleManualAuth = async () => {
try {
// Get nonce
const nonce = await getNonce();
// Create message
const message = createSignInMessage(
address!,
nonce,
'example.com'
);
// Sign message (you would do this with walletClient)
// const signature = await walletClient.signMessage({ message: message.message });
// Authenticate
// await authenticate();
} catch (error) {
console.error('Authentication failed:', error);
}
};Auth Caching
The hook automatically caches authentication responses:
- Storage: LocalStorage (per address)
- Expiration: Based on
authExpiresfrom server - Auto-load: Cached auth is loaded on mount
EIP-712 Document Creation
The hook provides helpers for creating EIP-712 documents:
const {
createEip712DocForOrder,
createEip712DocForWalletGeneration,
} = useAuth({
client,
address: address!,
walletClient,
});
// Create EIP-712 doc for order
const orderDoc = createEip712DocForOrder(quoteResponse);
// Create EIP-712 doc for wallet generation
const walletDoc = createEip712DocForWalletGeneration(
`eip155:43114:${address}`, // Scope
auth.secretToken // Token
);Error Handling
const { auth, error, signIn } = useAuth({
client,
address: address!,
walletClient,
});
const handleSignIn = async () => {
try {
const result = await signIn();
if (!result) {
console.error('Sign in returned null');
}
} catch (err) {
console.error('Sign in error:', err);
}
};
// Display errors
{error && (
<div className="error">
Authentication failed: {error.message}
</div>
)}Best Practices
- Enable Auto-Authentication - Use
autoAuthenticate: truefor better UX - Handle Loading States - Show loading indicators during authentication
- Check Authentication - Use
isAuthenticated()before protected operations - Error Recovery - Provide retry mechanisms for failed authentication
- Sign Out - Clear auth state when user disconnects wallet
Next Steps
- Learn about wallet generation
- Understand quote and execution
- See complete example