Enka.DotNet

March 9, 2026 · View on GitHub

Enka.DotNet is a C# wrapper for accessing and processing character data from the Enka.Network API. It provides a simple interface to retrieve detailed information about characters, artifacts, weapons, and player profiles for Genshin Impact, Honkai: Star Rail, and Zenless Zone Zero.

NuGet Quality Gate Status Code Smells Reliability Rating Security Rating Maintainability Rating Vulnerabilities

Features

  • Multi-Game Support: Genshin Impact, Honkai: Star Rail, and Zenless Zone Zero
  • Strongly Typed Models: Clear and user-friendly C# models for all entities
  • Flexible Client Setup:
    • Direct Instantiation: await EnkaClient.CreateAsync(options)
    • Dependency Injection: services.AddEnkaNetClient(options => { ... })
  • HTTP Resiliency: Polly-powered retry with exponential backoff + jitter, circuit breaker, and 429 Retry After support
  • Multi-Provider Caching: Memory (default), SQLite, Redis, or custom IEnkaCache
  • Asset Preloading: Warm up game assets at startup for zero-latency first requests
  • Observability: OpenTelemetry ActivitySource + System.Diagnostics.Metrics hooks for traces and metrics

Supported Games

GameStatusMethod
Genshin Impact✅ ReadyUID
Honkai: Star Rail✅ ReadyUID
Zenless Zone Zero✅ ReadyUID

Miscellaneous

FeatureStatusMethod
Fetch Basic Profile✅ ReadyEnka Username
Genshin Impact✅ ReadyEnka Username
Honkai: Star Rail✅ ReadyEnka Username
Zenless Zone Zero✅ ReadyEnka Username

Installation

dotnet add package EnkaDotNet

Usage & Examples

Enka.DotNet supports both direct instantiation and Dependency Injection.

Direct Instantiation

var options = new EnkaClientOptions
{
    EnableCaching = true,
    CacheDurationMinutes = 10,
    UserAgent = "MyApp/1.0"
};
await using IEnkaClient client = await EnkaClient.CreateAsync(options);

Dependency Injection (ASP.NET Core / Worker Service)

builder.Services.AddEnkaNetClient(options =>
{
    options.EnableCaching = true;
    options.CacheDurationMinutes = 10;

    // Warm up assets at startup (runs via IHostedService, never blocks DI thread)
    options.PreloadedLanguages = new List<Language> { Language.English, Language.Japanese };
});

For detailed runnable examples, see the Examples/ directory in the repository.

Caching

Cache Providers

Configure the cache provider via EnkaClientOptions.CacheProvider:

// In memory (default)
options.CacheProvider = CacheProvider.Memory;

// SQLite (persistent across restarts, no external dependency)
options.CacheProvider = CacheProvider.SQLite;
options.SQLiteCache = new SQLiteCacheOptions
{
    DatabasePath = "enka_cache.db",
    DefaultTtl = TimeSpan.FromMinutes(10)
};

// Redis (distributed, for multi instance apps)
options.CacheProvider = CacheProvider.Redis;
options.RedisCache = new RedisCacheOptions
{
    ConnectionString = "localhost:6379",
    KeyPrefix = "myapp:enka:"
};

Runtime Cache Control

// Force fresh data for one call
var profile = await client.GetGenshinPlayerInfoAsync(uid, bypassCache: true);

// Clear all cached entries
client.ClearCache();

// Get cache statistics
var (count, _) = client.GetCacheStats();

Language

All game API methods accept a Language enum for type safe language selection:

// Using Language enum (recommended)
var playerInfo = await client.GetZZZPlayerInfoAsync(uid, Language.Japanese);
var hsrInfo    = await client.GetHSRPlayerInfoAsync(uid, Language.TraditionalChinese);
var giInfo     = await client.GetGenshinPlayerInfoAsync(uid, Language.German);

// Using string (still supported)
var playerInfo = await client.GetZZZPlayerInfoAsync(uid, language: "ja");

Available languages:

Enum ValueString Code
Language.Englishen
Language.Russianru
Language.Vietnamesevi
Language.Thaith
Language.Portuguesept
Language.Koreanko
Language.Japaneseja
Language.Indonesianid
Language.Frenchfr
Language.Spanishes
Language.Germande
Language.TraditionalChinesezh-tw
Language.SimplifiedChinesezh-cn
Language.Italianit
Language.Turkishtr

HTTP Resiliency

Resiliency is configured via EnkaClientOptions:

options.MaxRetries = 3;                         // Retry attempts (default: 1)
options.RetryDelayMs = 1000;                    // Base delay in ms (default: 1000)
options.UseExponentialBackoff = true;           // Exponential backoff with jitter (default: true)
options.MaxRetryDelayMs = 30000;                // Cap on retry delay (default: 30000)
options.CircuitBreakerFailureThreshold = 5;     // Failures before circuit opens (default: 5)
options.CircuitBreakerBreakDurationSeconds = 30; // Seconds circuit stays open (default: 30)

429 Too Many Requests is automatically retried using the Retry-After response header as the delay. A RateLimitException is only thrown after all retry attempts are exhausted.

Observability

The library exposes OpenTelemetry hooks with no additional dependencies. Wire up your own exporters:

// Distributed tracing
builder.Services.AddOpenTelemetry()
    .WithTracing(t => t.AddSource("EnkaDotNet").AddOtlpExporter());

// Metrics (counters + request duration histogram)
builder.Services.AddOpenTelemetry()
    .WithMetrics(m => m.AddMeter("EnkaDotNet").AddPrometheusExporter());

Exposed metrics:

MetricDescription
enka.requests.totalTotal API requests made
enka.cache.hitsCache hit count
enka.cache.missesCache miss count
enka.retries.totalTotal retry attempts
enka.request.duration (ms)Request duration histogram

Asset Preloading

Preloading warms up the in-memory asset cache at startup so the first real request has zero asset-load latency:

// Direct instantiation
await using var client = await EnkaClient.CreateAsync(new EnkaClientOptions
{
    PreloadedLanguages = new List<Language> { Language.English, Language.Japanese }
});

// DI (runs asynchronously via IHostedService)
builder.Services.AddEnkaNetClient(options =>
{
    options.PreloadedLanguages = new List<Language> { Language.English, Language.Japanese };
});

Asset Fallback (Offline / GitHub Unavailable)

Set AssetFallbackDirectory to make the library resilient to network outages. The first time an asset is downloaded successfully it is saved to disk. If a subsequent download fails (GitHub down, no internet), the saved copy is served instead.

options.AssetFallbackDirectory = "/path/to/your/enka_assets";

By default (null) nothing is ever written to disk.

Where do the files go?

The path is set by your application, the library just reads and writes to wherever you point it. The NuGet package folder (~/.nuget/packages/enkadotnet/) is read only and shared, files are never written there.

App typeRecommended pathResolves to (example)
ASP.NET Core / Worker ServicePath.Combine(builder.Environment.ContentRootPath, "enka_assets")/myapp/enka_assets/
Console appPath.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "EnkaDotNet", "assets")C:/Users/john/AppData/Local/EnkaDotNet/assets
DockerMount a volume and set the path explicitly/data/enka_assets

Avoid using AppContext.BaseDirectory that resolves to the build output folder (bin/Release/net8.0/) which is wiped on each rebuild.

Full ASP.NET Core example:

builder.Services.AddEnkaNetClient(options =>
{
    // Writes to <project-root>/enka_assets/ which survives rebuilds
    options.AssetFallbackDirectory =
        Path.Combine(builder.Environment.ContentRootPath, "enka_assets");

    options.PreloadedLanguages = new List<Language> { Language.English, Language.Japanese };
});

Saved file layout:

enka_assets/
  genshin/ characters.json  text_map.json  namecards.json  ...
  hsr/     honker_characters.json  honker_weps.json  ...
  zzz/     avatars.json  weapons.json  property.json  ...

Requirements

  • .NET Standard 2.0 compatible framework (.NET Core 2.0+, .NET Framework 4.6.1+, .NET 5+)

Support

Having questions or issues? Join our Discord server: Alg's Dev Env

License

This project is licensed under the Apache 2.0 License - see the LICENSE file for details.

Acknowledgments


Disclaimer

This project is not affiliated with or endorsed by HoYoverse (COGNOSPHERE PTE. LTD.) or Enka.Network. Genshin Impact, Honkai: Star Rail, and Zenless Zone Zero are trademarks of HoYoverse.