onEnable() and you’re done. The Self-Cleaning architecture releases the license seat automatically on shutdown or /reload, so you do not need any cleanup in onDisable().
Installation
Kotlin (one-liner)
Java
Wrap the blockingcheck call in Bukkit’s async scheduler:
Configuration
Customize global behavior before validation runs:How validation works
- Fetches your plugin’s Ed25519 public key from the API.
- Reads the buyer’s
nmkey.txtbundled inside the jar (NMCrate bakes it in at download). - Generates an in-memory heuristic fingerprint of the host.
- Posts the payload and a nonce to the validation endpoint.
- Verifies the Ed25519 signature and encrypts the response to disk using the fingerprint as the AES-GCM key.
- If the network fails, decrypts the local cache — validation succeeds offline while the fingerprint matches and the cache is younger than
gracePeriodHours.
NMKey.check and NMKey.release are blocking; run them async (the Kotlin extension does this for you). Manual release is no longer necessary — the Self-Cleaning listener handles it.
Obfuscation (crucial)
Run your final jar through an obfuscator (ProGuard, Zelix KlassMaster, Stringer) and make sure the shadedcom.nmcrate.key package is heavily obfuscated:
- Control-flow obfuscation to scramble the signature-checking logic.
- String encryption to hide the API endpoints and JSON keys.