Skip to content

Latest commit

 

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HALO — by Corino

A JUCE 8 standalone GUI application that doubles as a reference implementation of the Moonbase C++ activation SDK.

HALO is presented as if it were a harmonic saturator plug-in — it has a transfer-function display, a Drive knob, stage toggles, Tone/Mix knobs, an animated I/O meter — but it does not process audio. Everything visible is decorative. The point of the project is the surrounding license-gate workflow: how a JUCE app talks to Moonbase to activate, persist a JWT, validate it on startup, and revoke it.

On startup the bridge runs a synchronous local check of the cached JWT (signature + device fingerprint + expiry) so the UI unlocks immediately, then kicks off an online re-validation against the Moonbase API on a background thread. Within a configurable throttle window (online_validation_min_interval, default 5 minutes) the API call is skipped; beyond it the SDK refreshes the token. A online_validation_grace_period (default 7 days) lets the app stay unlocked through transient transport failures — past that, the user is bounced back to the activation screen.

HALO activation screen

The build produces a single drag-and-droppable artefact — no installer:

Platform Output
macOS build/HALO_artefacts/Release/HALO.app
Windows build/HALO_artefacts/Release/HALO.exe
Linux build/HALO_artefacts/Release/HALO

What it demonstrates

  • moonbase::juce_bridge::MoonbaseUnlockStatus — JUCE-side wrapper around Moonbase's JWT/browser activation flow, subclassing juce::OnlineUnlockStatus.
  • MoonbaseJuceFingerprintProvider — sources the device fingerprint from juce::SystemStats::getUniqueDeviceID().
  • applyJuceMetadata(options) — populates Moonbase metadata from JUCE's system/host helpers.
  • tryLoadStoredLicenseAsync — non-blocking startup validation.
  • beginActivation() → pollPendingActivation() — the browser-based activation handshake.
  • revokeActivationAsync() — wired to a Sign out menu item behind the settings cog.
  • file_license_store — persists the validated JWT under the platform's per-user app data directory (~/Library/Application Support/Corino/HALO/ on macOS).

The SDK is configured against the Corino demo tenant API at https://corino-demo.moonbase.sh (product halo). When the user clicks Activate, the Moonbase merchant routes the browser to the customer-facing landing page at corino.moonbase.sh for sign-in / purchase / trial fulfilment — the API host and the landing host are intentionally different.

Build

macOS

brew install cmake ninja openssl@3 nlohmann-json
cmake -B build -S . -G Ninja
cmake --build build -j

The first configure pulls JUCE 8.0.4 and moonbase-cpp v3.0.0 via FetchContent (~80 MB). First build takes a few minutes while JUCE compiles. Subsequent rebuilds are fast.

On systems where /usr/bin/c++ is paired with a stale macOS SDK you may need to point CMake at a working sysroot, e.g.:

SDKROOT=$(xcrun --sdk macosx --show-sdk-path) cmake -B build -S . -G Ninja

OpenSSL is statically linked (OPENSSL_USE_STATIC_LIBS=TRUE) so the resulting .app does not depend on Homebrew paths — the only non-system dependency is /usr/lib/libcurl.4.dylib, which ships with macOS.

The build is unsigned; macOS will quarantine it on download. For local use, ad-hoc sign it:

codesign --force --deep -s - build/HALO_artefacts/Release/HALO.app

Windows

Requires Visual Studio 2022 + vcpkg for libcurl/OpenSSL/nlohmann_json:

vcpkg install curl[ssl] openssl nlohmann-json --triplet x64-windows-static
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=path\to\vcpkg.cmake `
  -DVCPKG_TARGET_TRIPLET=x64-windows-static
cmake --build build --config Release

Linux

sudo apt install build-essential cmake ninja-build libcurl4-openssl-dev libssl-dev nlohmann-json3-dev
cmake -B build -S . -G Ninja
cmake --build build -j

End-to-end test

  1. Launch the app. The activation screen appears (no stored license).
  2. Click Activate → a browser window opens at corino.moonbase.sh (the Corino landing page, served by the Moonbase merchant).
  3. Sign in / fulfil the activation in the browser.
  4. Within ~1 second the app flips to the plugin UI.
  5. Quit and relaunch — the app skips the activation screen, running the local JWT check synchronously and then revalidating against the API in the background. The license lives at ~/Library/Application Support/Corino/HALO/license.mb.
  6. Open the cog menu → License details… to inspect the active license, or Sign out (revoke activation) to release the seat on the server and clear the local license.

CI

.github/workflows/ci.yml runs on every pull request (and on push to main) and builds HALO on both macos-14 and windows-2022, including the same portability checks the release pipeline runs (otool -L on macOS; dumpbin /DEPENDENTS allow-list on Windows). It doesn't publish anything — it's purely a "this branch can still ship" gate.

CI and release share the underlying build logic via composite actions under .github/actions/build-halo-{macos,windows}/, so a green CI run is a real guarantee the release workflow can produce binaries.

Releasing

.github/workflows/release.yml builds HALO on a macOS runner and publishes it straight to the Moonbase tenant as a new product release, following the GitHub Actions guide.

One-time setup

  1. In the Moonbase tenant dashboard, create a merchant API key with permission to manage product downloads.
  2. In this repository → Settings → Secrets and variables → Actions, add a secret named MOONBASE_API_KEY containing that key.
  3. Confirm MOONBASE_TENANT_HOST and MOONBASE_PRODUCT_ID at the top of the workflow match the SDK config in src/license/HaloLicenseBridge.cpp (default: corino-demo.moonbase.sh / halo).

Cutting a release

git tag v1.0.1
git push origin v1.0.1

The workflow

  1. Builds HALO.app on macos-14, ad-hoc signs it, and zips it with ditto -c -k --keepParent so the bundle structure and xattrs survive.
  2. POST /api/downloads/prepare?contentType=application/octet-stream → gets a signed upload URL and content key.
  3. PUT the zipped bundle to the signed URL.
  4. POST /api/products/halo/releases/new?publishImmediately=true with the release payload (version: { major, minor, patch }, downloads: [{ name, platform: "Mac", key }]).

You can also run the workflow manually from the Actions tab — supply the version (1.2.3) and choose whether to publish immediately or leave the release as a draft for review in the Moonbase dashboard.

Builds run in parallel on macos-14 (arm64) and windows-2022 (x64). The publish job waits for both, then posts a single release with two downloads attached. Windows uses vcpkg in manifest mode (vcpkg.json at the repo root) with the x64-windows-static triplet so the .exe is a single file with no runtime DLL dependencies. A vcpkg GitHub-Actions binary cache makes repeat installs of curl/OpenSSL/nlohmann-json fast.

A Linux build can be added as another build-* job following the same pattern; the publish-release payload just grows another entry in the downloads array.

Source layout

CMakeLists.txt              # FetchContent JUCE + moonbase-cpp, juce_add_gui_app
resources/fonts/            # Bundled fonts (Space Grotesk, JetBrains Mono, Inter)
src/
  Main.cpp                  # START_JUCE_APPLICATION(HaloApplication)
  HaloApplication.{h,cpp}   # DocumentWindow at 760×460, non-resizable
  MainComponent.{h,cpp}     # Owns the bridge, swaps Activation ↔ Plugin
  HaloLookAndFeel.{h,cpp}   # Bundled-font wiring
  Branding.h                # Palette + font names + background painter
  ActivationScreen.{h,cpp}  # CTA → bridge.beginActivation() → poll
  PluginScreen.{h,cpp}      # Transfer curve + knobs + footer
  license/
    MoonbaseJuceBridge.h    # Vendored copy from moonbase-cpp v3.0.0
    HaloLicenseBridge.{h,cpp} # Demo-tenant wrapper around MoonbaseUnlockStatus
  ui/
    HaloKnob.{h,cpp}        # Conic-gradient knob (segmented approximation)
    TransferCurve.{h,cpp}   # tanh curve + animated dot
    StageToggle.{h,cpp}     # Preamp / Head / Bias pill row
    MiniMeter.{h,cpp}       # Footer IN/OUT animated meter
    PresetSelector.{h,cpp}  # Header preset row

Design

The visual identity is recreated from the Corino Plugins design canvas: warm-dark gradient background, amber accent (oklch(0.78 0.16 65)), Space Grotesk for display type, JetBrains Mono for technical labels, Inter for body.

License

This sample is MIT-licensed — see LICENSE. JUCE 8 is licensed separately — see JUCE's licensing terms; this project consumes JUCE under the GPLv3 path implicit in FetchContent. The Moonbase SDK is MIT-licensed. Bundled fonts ship under their respective SIL OFL licenses.

About

Reference implementation for moonbase-cpp licensing in a JUCE app

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages