userRole
Get role information for a user on Hyperliquid, including permissions, access levels, and account capabilities.
When to Use This Endpoint#
The userRole endpoint is essential for:
- Permission Checking — Verify user access levels and capabilities
- Access Control — Implement role-based access in applications
- Feature Gating — Enable/disable features based on user role
- Account Management — Understand account type and permissions
Request#
Endpoint#
POST https://api-hyperliquid-mainnet-info.n.dwellir.com/info
Headers#
| Header | Value | Required |
|---|---|---|
Content-Type | application/json | Yes |
X-Api-Key | Your API key | Yes |
Parameters#
| Parameter | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Must be "userRole" |
user | string | Yes | User's Ethereum wallet address |
Example Request#
{
"type": "userRole",
"user": "0x63E8c7C149556D5f34F833419A287bb9Ef81487f"
}
Response#
Success Response#
Returns role information for the specified user.
{
"role": "standard"
}
Response Fields#
| Field | Type | Description |
|---|---|---|
role | string | User's role on the platform (e.g., "standard", "vip", "market_maker") |
Code Examples#
- cURL
- JavaScript
- Python
- Go
curl -X POST 'https://api-hyperliquid-mainnet-info.n.dwellir.com/info' \
-H 'X-Api-Key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"type": "userRole",
"user": "0x63E8c7C149556D5f34F833419A287bb9Ef81487f"
}'
const ENDPOINT = 'https://api-hyperliquid-mainnet-info.n.dwellir.com/info';
const API_KEY = 'your-api-key-here';
async function getUserRole(userAddress) {
const response = await fetch(ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': API_KEY
},
body: JSON.stringify({
type: 'userRole',
user: userAddress
})
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return await response.json();
}
// Usage
const roleData = await getUserRole('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
console.log(`User role: ${roleData.role}`);
import requests
from typing import Dict
ENDPOINT = 'https://api-hyperliquid-mainnet-info.n.dwellir.com/info'
API_KEY = 'your-api-key-here'
def get_user_role(user_address: str) -> Dict:
"""Get user role information"""
response = requests.post(
ENDPOINT,
json={
'type': 'userRole',
'user': user_address
},
headers={
'Content-Type': 'application/json',
'X-Api-Key': API_KEY
},
timeout=10
)
response.raise_for_status()
return response.json()
# Usage
role_data = get_user_role('0x63E8c7C149556D5f34F833419A287bb9Ef81487f')
print(f"User role: {role_data['role']}")
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
const (
Endpoint = "https://api-hyperliquid-mainnet-info.n.dwellir.com/info"
APIKey = "your-api-key-here"
)
type UserRoleRequest struct {
Type string `json:"type"`
User string `json:"user"`
}
type UserRoleResponse struct {
Role string `json:"role"`
}
func getUserRole(userAddress string) (*UserRoleResponse, error) {
reqBody, _ := json.Marshal(UserRoleRequest{
Type: "userRole",
User: userAddress,
})
req, _ := http.NewRequest("POST", Endpoint, bytes.NewBuffer(reqBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-Api-Key", APIKey)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
var result UserRoleResponse
if err := json.Unmarshal(body, &result); err != nil {
return nil, err
}
return &result, nil
}
func main() {
roleData, err := getUserRole("0x63E8c7C149556D5f34F833419A287bb9Ef81487f")
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("User role: %s\n", roleData.Role)
}
Common Use Cases#
1. Check User Permissions#
Verify user role for access control:
async function checkUserPermissions(userAddress) {
const roleData = await getUserRole(userAddress);
console.log('=== User Permissions ===\n');
console.log(`Role: ${roleData.role}`);
return roleData.role;
}
// Usage
const role = await checkUserPermissions('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
2. Role-Based Feature Access#
Implement role-based feature gating:
async function canAccessFeature(userAddress, featureName) {
const roleData = await getUserRole(userAddress);
// Define feature access by role
const featureAccess = {
standard: ['basic_trading', 'view_data'],
vip: ['basic_trading', 'view_data', 'advanced_analytics', 'priority_support'],
market_maker: ['basic_trading', 'view_data', 'advanced_analytics', 'market_making', 'api_access']
};
const userFeatures = featureAccess[roleData.role] || [];
const hasAccess = userFeatures.includes(featureName);
console.log(`Feature "${featureName}": ${hasAccess ? 'Granted' : 'Denied'}`);
return hasAccess;
}
// Usage
const canUseAdvancedAnalytics = await canAccessFeature(
'0x63E8c7C149556D5f34F833419A287bb9Ef81487f',
'advanced_analytics'
);
3. Display Role Badge#
Show user role in UI:
async function getUserRoleBadge(userAddress) {
const roleData = await getUserRole(userAddress);
const badges = {
standard: { label: 'Standard', color: 'gray' },
vip: { label: 'VIP', color: 'gold' },
market_maker: { label: 'Market Maker', color: 'blue' }
};
return badges[roleData.role] || { label: 'User', color: 'gray' };
}
// Usage
const badge = await getUserRoleBadge('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
console.log(`Display badge: ${badge.label} (${badge.color})`);
4. Build Access Control System#
Create comprehensive access control:
class AccessControl {
constructor(userAddress) {
this.userAddress = userAddress;
this.role = null;
}
async initialize() {
const roleData = await getUserRole(this.userAddress);
this.role = roleData.role;
return this.role;
}
hasPermission(permission) {
const permissions = {
standard: ['read', 'basic_trade'],
vip: ['read', 'basic_trade', 'advanced_trade', 'analytics'],
market_maker: ['read', 'basic_trade', 'advanced_trade', 'analytics', 'market_make', 'api']
};
const userPermissions = permissions[this.role] || [];
return userPermissions.includes(permission);
}
getPermissions() {
const permissions = {
standard: ['read', 'basic_trade'],
vip: ['read', 'basic_trade', 'advanced_trade', 'analytics'],
market_maker: ['read', 'basic_trade', 'advanced_trade', 'analytics', 'market_make', 'api']
};
return permissions[this.role] || [];
}
}
// Usage
const acl = new AccessControl('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
await acl.initialize();
if (acl.hasPermission('advanced_trade')) {
console.log('User can access advanced trading');
}
5. Role-Based Dashboard#
Customize dashboard based on user role:
async function buildRoleBasedDashboard(userAddress) {
const roleData = await getUserRole(userAddress);
const dashboardConfig = {
standard: {
widgets: ['account_summary', 'basic_charts', 'order_book'],
features: ['basic_trading']
},
vip: {
widgets: ['account_summary', 'advanced_charts', 'order_book', 'analytics'],
features: ['basic_trading', 'advanced_trading', 'analytics']
},
market_maker: {
widgets: ['account_summary', 'advanced_charts', 'order_book', 'analytics', 'api_stats'],
features: ['basic_trading', 'advanced_trading', 'analytics', 'market_making', 'api_access']
}
};
const config = dashboardConfig[roleData.role] || dashboardConfig.standard;
return {
role: roleData.role,
dashboard: config,
timestamp: new Date().toISOString()
};
}
// Usage
const dashboard = await buildRoleBasedDashboard('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
console.log('Dashboard configuration:', dashboard);
Error Handling#
Common Errors#
| Error | Cause | Solution |
|---|---|---|
401 Unauthorized | Invalid API key | Verify your API key is correct |
400 Bad Request | Missing or invalid user address | Ensure valid Ethereum address format |
429 Too Many Requests | Rate limit exceeded | Implement request throttling |
500 Internal Server Error | Server issue | Retry with exponential backoff |
Error Response Example#
{
"error": "Missing required parameter: user",
"code": "MISSING_PARAMETER"
}
Robust Error Handling#
async function safeGetUserRole(userAddress, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await getUserRole(userAddress);
} catch (error) {
if (error.response?.status === 429) {
await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000));
} else if (error.response?.status === 400) {
throw new Error('Invalid user address');
} else if (i === maxRetries - 1) {
throw error;
}
}
}
}
Best Practices#
- Cache role data — Role changes infrequently, cache for 5-10 minutes
- Validate addresses — Ensure user addresses are valid Ethereum addresses
- Default to least privilege — Use most restrictive role as default
- Handle unknown roles — Have fallback for unrecognized roles
- Implement feature flags — Combine with feature flags for flexible access control
Performance Tips#
Cached Role Checker#
class CachedRoleChecker {
constructor(cacheDurationMs = 300000) {
this.cache = new Map();
this.cacheDurationMs = cacheDurationMs; // 5 minutes
}
async getRole(userAddress) {
const cached = this.cache.get(userAddress);
const now = Date.now();
if (cached && (now - cached.timestamp) < this.cacheDurationMs) {
return cached.role;
}
const roleData = await getUserRole(userAddress);
this.cache.set(userAddress, {
role: roleData.role,
timestamp: now
});
return roleData.role;
}
invalidate(userAddress) {
this.cache.delete(userAddress);
}
clearAll() {
this.cache.clear();
}
}
// Usage
const roleChecker = new CachedRoleChecker();
const role = await roleChecker.getRole('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
Related Endpoints#
- extraAgents — Get agent information
- subAccounts — Get sub-account details
- clearinghouseState — Get account state
- userFees — Get fee information (may vary by role)
Implement role-based access control with Dwellir's HyperCore Info Endpoint. Get your API key →