> For the complete documentation index, see [llms.txt](https://docs.heyhal.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.heyhal.xyz/api-documentation/get-current-user.md).

# Get Current User

**Endpoint:** <mark style="color:yellow;">`GET /api/v1/me`</mark>

### Description

This endpoint returns information about the currently authenticated user. It uses the user information from the request object, which is populated by the authentication middleware.

### Authentication

Required: Yes

Type: Bearer Token (JWT)

### Request

#### Headers

#### Content-Type: application/json

#### Authorization: Bearer \<your\_jwt\_token>

No query parameters or body required.

### Response

#### Success Response

Status Code: 200 OK

Content-Type: application/json

interface CurrentUserResponse {

&#x20; user: {

&#x20;   id: string;

&#x20;   walletAddress: string;

&#x20;   username: string | null;

&#x20;   role: string;

&#x20;   lastLogin: string;

&#x20;   createdAt: string;

&#x20;   updatedAt: string;

&#x20; }

}

Example Response:

{

&#x20; "user": {

&#x20;   "id": "user123",

&#x20;   "walletAddress": "SolanaWalletAddress123...",

&#x20;   "username": "cryptoTrader",

&#x20;   "role": "user",

&#x20;   "lastLogin": "2024-02-20T12:00:00.000Z",

&#x20;   "createdAt": "2024-01-01T00:00:00.000Z",

&#x20;   "updatedAt": "2024-02-20T12:00:00.000Z"

&#x20; }

}

### Example Usage

### // Basic implementation

### async function getCurrentUser() {

### &#x20; try {

### &#x20;   const response = await fetch('<https://api.heyhal.xyz/api/v1/me>', {

### &#x20;     headers: {

### &#x20;       'Authorization': \`Bearer ${localStorage.getItem('auth\_token')}\`

### &#x20;     }

### &#x20;   });

### &#x20;   if (!response.ok) {

### &#x20;     throw new Error(\`HTTP error! status: ${response.status}\`);

### &#x20;   }

### &#x20;   const { user } = await response.json();

### &#x20;   return user;

### &#x20; } catch (error) {

### &#x20;   console.error('Error fetching current user:', error);

### &#x20;   throw error;

### &#x20; }

### }

### // React Hook example

### function useCurrentUser() {

### &#x20; const \[user, setUser] = useState(null);

### &#x20; const \[loading, setLoading] = useState(true);

### &#x20; const \[error, setError] = useState(null);

### &#x20; useEffect(() => {

### &#x20;   async function fetchUser() {

### &#x20;     try {

### &#x20;       const userData = await getCurrentUser();

### &#x20;       setUser(userData);

### &#x20;     } catch (err) {

### &#x20;       setError(err.message);

### &#x20;     } finally {

### &#x20;       setLoading(false);

### &#x20;     }

### &#x20;   }

### &#x20;   fetchUser();

### &#x20; }, \[]);

### &#x20; return { user, loading, error };

### }

### Implementation Notes

1\. Authentication Check

// Example middleware to verify authentication

function requireAuth(req: FastifyRequest, reply: FastifyReply) {

&#x20; if (!req.user) {

&#x20;   reply.code(401).send({

&#x20;     error: 'Authentication required'

&#x20;   });

&#x20;   return;

&#x20; }

}

User Session Management

class UserSessionManager {

&#x20; private static instance: UserSessionManager;

&#x20; private currentUser: any = null;

&#x20; private lastFetch: number = 0;

&#x20; private readonly CACHE\_DURATION = 300000; // 5 minutes

&#x20; static getInstance() {

&#x20;   if (!UserSessionManager.instance) {

&#x20;     UserSessionManager.instance = new UserSessionManager();

&#x20;   }

&#x20;   return UserSessionManager.instance;

&#x20; }

&#x20; async getCurrentUser(forceRefresh = false) {

&#x20;   const now = Date.now();

&#x20;   if (

&#x20;     forceRefresh ||&#x20;

&#x20;     !this.currentUser ||&#x20;

&#x20;     now - this.lastFetch > this.CACHE\_DURATION

&#x20;   ) {

&#x20;     const user = await getCurrentUser();

&#x20;     this.currentUser = user;

&#x20;     this.lastFetch = now;

&#x20;   }

&#x20;   return this.currentUser;

&#x20; }

&#x20; clearCache() {

&#x20;   this.currentUser = null;

&#x20;   this.lastFetch = 0;

&#x20; }

}

Error Handling

class AuthenticationError extends Error {

&#x20; constructor(message = 'Authentication required') {

&#x20;   super(message);

&#x20;   this.name = 'AuthenticationError';

&#x20; }

}

async function getAuthenticatedUser() {

&#x20; try {

&#x20;   const response = await fetch('<https://api.heyhal.xyz/api/v1/me>', {

&#x20;     headers: {

&#x20;       'Authorization': \`Bearer ${localStorage.getItem('auth\_token')}\`

&#x20;     }

&#x20;   });

&#x20;   if (response.status === 401) {

&#x20;     throw new AuthenticationError();

&#x20;   }

&#x20;   if (!response.ok) {

&#x20;     throw new Error('Failed to fetch user data');

&#x20;   }

&#x20;   return response.json();

&#x20; } catch (error) {

&#x20;   if (error instanceof AuthenticationError) {

&#x20;     // Handle authentication errors

&#x20;     window\.location.href = '/login';

&#x20;   }

&#x20;   throw error;

&#x20; }

}

### Best Practices

1\. Token Management

class TokenManager {

&#x20; private static readonly TOKEN\_KEY = 'auth\_token';

&#x20; private static readonly TOKEN\_EXPIRY\_KEY = 'auth\_token\_expiry';

&#x20; static getToken(): string | null {

&#x20;   const token = localStorage.getItem(this.TOKEN\_KEY);

&#x20;   const expiry = localStorage.getItem(this.TOKEN\_EXPIRY\_KEY);

&#x20;   if (!token || !expiry) {

&#x20;     return null;

&#x20;   }

&#x20;   if (Date.now() > Number(expiry)) {

&#x20;     this.clearToken();

&#x20;     return null;

&#x20;   }

&#x20;   return token;

&#x20; }

&#x20; static setToken(token: string, expiresIn: number) {

&#x20;   localStorage.setItem(this.TOKEN\_KEY, token);

&#x20;   localStorage.setItem(

&#x20;     this.TOKEN\_EXPIRY\_KEY,&#x20;

&#x20;     String(Date.now() + expiresIn \* 1000)

&#x20;   );

&#x20; }

&#x20; static clearToken() {

&#x20;   localStorage.removeItem(this.TOKEN\_KEY);

&#x20;   localStorage.removeItem(this.TOKEN\_EXPIRY\_KEY);

&#x20; }

}

User Data Validation

function validateUserData(user: any): boolean {

&#x20; return !!(

&#x20;   user &&

&#x20;   typeof user.walletAddress === 'string' &&

&#x20;   typeof user.role === 'string' &&

&#x20;   typeof user.lastLogin === 'string'

&#x20; );

}

function sanitizeUserData(user: any) {

&#x20; return {

&#x20;   id: user.id,

&#x20;   walletAddress: user.walletAddress,

&#x20;   username: user.username || null,

&#x20;   role: user.role,

&#x20;   lastLogin: user.lastLogin,

&#x20;   createdAt: user.createdAt,

&#x20;   updatedAt: user.updatedAt

&#x20; };

}

3\. Request Retry Logic

async function fetchWithRetry(

&#x20; url: string,&#x20;

&#x20; options: RequestInit,&#x20;

&#x20; maxRetries = 3

) {

&#x20; let attempts = 0;

&#x20;&#x20;

&#x20; while (attempts < maxRetries) {

&#x20;   try {

&#x20;     const response = await fetch(url, options);

&#x20;    &#x20;

&#x20;     if (response.ok) {

&#x20;       return response.json();

&#x20;     }

&#x20;    &#x20;

&#x20;     if (response.status === 401) {

&#x20;       throw new AuthenticationError();

&#x20;     }

&#x20;    &#x20;

&#x20;   } catch (error) {

&#x20;     attempts++;

&#x20;    &#x20;

&#x20;     if (attempts === maxRetries || error instanceof AuthenticationError) {

&#x20;       throw error;

&#x20;     }

&#x20;    &#x20;

&#x20;     await new Promise(resolve =>&#x20;

&#x20;       setTimeout(resolve, 1000 \* attempts)

&#x20;     );

&#x20;   }

&#x20; }

&#x20;&#x20;

&#x20; throw new Error('Max retry attempts reached');

}

<br>
