> 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>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.heyhal.xyz/api-documentation/get-current-user.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
