Skip to content

trqlmao/club.fernan.api

Repository files navigation

club.fernan.api

build JitPack Java 17+ License: MIT Issues Stars

Drop-in Java client for the fernan.club REST API. Async-first, JDK 17+, zero dependencies beyond Gson, safe to embed in mods, launchers, or standalone JVM apps.

Unofficial. This project is community tooling. It is not affiliated with, endorsed by, or sponsored by fernan.club. The maintainer receives no compensation from fernan.club, does not operate any part of the upstream service, and does not vouch for the goods or services it delivers. Read the full DISCLAIMER before using.

  • One FernanClient entry point exposing five typed services (user, store, refunds, referrals, health).
  • All endpoints return CompletableFuture<T>.
  • One FernanException with a typed ErrorType enum covering every API error mode (auth, banned, validation, not-found, conflict, cooldown, rate-limit, server error).
  • Explicit ReferralChoice type — the library never silently auto-applies a referral code; the caller decides per call.
  • Optional X-Integration partner-attribution signal for client devs who want fernan.club to know who's driving traffic.

Install

Gradle (Kotlin DSL)

repositories {
    maven { url = uri("https://jitpack.io") }
}

dependencies {
    implementation("com.github.trqlmao:club.fernan.api:0.3.0")
}

Gradle (Groovy DSL)

repositories {
    maven { url 'https://jitpack.io' }
}

dependencies {
    implementation 'com.github.trqlmao:club.fernan.api:0.3.0'
}

Maven

<repositories>
  <repository>
    <id>jitpack.io</id>
    <url>https://jitpack.io</url>
  </repository>
</repositories>

<dependency>
  <groupId>com.github.trqlmao</groupId>
  <artifactId>club.fernan.api</artifactId>
  <version>0.3.0</version>
</dependency>

For AI agents

This library is intentionally structured so AI coding assistants (Claude Code, Copilot, Cursor, Cline, etc.) can wire it into your project in a single pass. If you're driving an agent, point it at:

  • CLAUDE.md — full integration guide written for AI consumption. Covers patterns, pitfalls, and threading.
  • llms.txt — structured index of every doc and example, per the llmstxt.org convention. Suitable for an agent to ingest as canonical context.
  • examples/ — three canonical integration patterns (minimal, alt-manager, error handling).

The surface area an agent has to learn is deliberately small: one entry point (FernanClient), five typed services, one exception (FernanException) with a typed ErrorType enum, and an explicit ReferralChoice value type that prevents an agent (or human) from silently auto-applying a referral code.

Quickstart

import club.fernan.api.FernanClient;
import club.fernan.api.model.referral.ReferralChoice;

FernanClient client = FernanClient.builder()
        .apiKey(System.getenv("FERNAN_KEY"))
        .userAgent("my-app/1.0")
        .integration("my-app")
        .build();

client.user().me()
        .thenAccept(me -> System.out.println("balance: " + me.balance()));

client.store().purchase(1, 5, ReferralChoice.none())
        .thenAccept(this::onPurchase)
        .exceptionally(t -> { onFailure(t); return null; });

// ... later, on app exit:
client.shutdown();

Don't use .join() outside CLI/script contexts. It blocks the calling thread (catastrophic on a render thread, Netty event loop, or game tick) and wraps exceptions in CompletionException. Chain with .thenAccept / .exceptionally instead. See CLAUDE.md for the threading model.

Services

Service Endpoints
client.user() me, apiKey, regenerateApiKey, redeemKey
client.store() stock, cooldowns, purchase, purchases, purchaseDetail, validateReferral
client.refunds() create, cancel, list, get
client.referrals() create, list, stats, toggle, delete (MediaPlus+)
client.health() get, simple

Recipes

See examples/ for self-contained snippets:

  • MinimalExample.java — smallest possible "build a client, fetch user, print balance".
  • AltManagerExample.java — canonical flow for clients with an alt-storage layer: list stock → prompt for referral → purchase → decode credentials → register with a host-app AltStore.
  • ErrorHandlingExample.java — recovering from rate limits, cooldowns, and insufficient-balance failures.

Referral codes

The library never silently applies a referral code. Every purchase requires an explicit ReferralChoice:

// Apply a code the user selected:
client.store().purchase(productId, qty, ReferralChoice.of("creator123"));

// User explicitly declined / no preference:
client.store().purchase(productId, qty, ReferralChoice.none());

If you surface referrals to end users, prompt them to choose rather than auto-defaulting to your own code.

Error handling

import club.fernan.api.exception.ErrorType;
import club.fernan.api.exception.FernanException;

client.store().purchase(1, 100, ReferralChoice.none())
        .exceptionally(t -> {
            FernanException e = (FernanException) t.getCause();
            switch (e.type()) {
                case INSUFFICIENT_BALANCE -> notifyTopUp();
                case COOLDOWN -> scheduleRetry(e.cooldownEndsAt());
                case RATE_LIMITED -> backoff(e.retryAfter());
                case AUTHENTICATION -> promptRelogin();
                default -> log(e);
            }
            return null;
        });

Locales

import club.fernan.api.locale.FernanLocale;

client.store().stock(FernanLocale.JA).join();

Supported: EN, ES, DE, JA, ZH, TW.

Integration signal

Identify your application to fernan.club without claiming referral revenue:

FernanClient.builder()
        .apiKey(key)
        .integration("my-app")
        .build();

This sends X-Integration: my-app on every request.

Roadmap

  • Next minor — wire UserService.preferredReferral() / preferredReferral(String) once the upstream endpoints are finalized.
  • Next minor — reconcile the X-Integration header with whatever final shape the upstream lands on.
  • Future — pluggable retry policy with exponential backoff for transient 5xx + 429 responses.

See CHANGELOG.md for released changes.

Requirements

  • Java 17 or newer (compiled with --release 17; verified on 17, 21, and 25).
  • One transitive dependency: Gson 2.11+.

Community

Activity

Repobeats analytics image

License

MIT.

About

Unofficial drop-in JDK 17+ Java Wrapper for fernan.club REST API

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Contributors

Languages