# AppsXi licensing SDKs Single-file SDKs, served at https://appsxi.com/sdk/. Two levels (PRD 15): - **Level 2, Sign in with AppsXi (recommended)**: the buyer clicks one button; your app gets a signed entitlement, starts trials in the app, and unlocks by itself after purchase. Guide: https://appsxi.com/docs/sign-in-with-appxi - **Level 1, license key**: the buyer enters the key from their library once. Guide: https://appsxi.com/docs/licensing ## Level 2: Sign in with AppsXi | | | | --- | --- | | Sign in | `signIn()` opens the browser (PKCE, loopback redirect); `signInWithCode()` for plugins (device code at /activate); AppsXi Desktop's one-time ticket is used automatically. | | Check | `check()` at launch: offline from the signed token, refreshed online once a day. Tokens are bound to this computer; a clock set back is refused. | | Trials | `startTrial()`: one per buyer account and per computer. `daysLeft`, `trialEndBehavior`. | | Buy | `openCheckout()` then `waitForUnlock()`: unlocks without a restart or a key. | | Sign out | `signOut()` frees this computer's seat. | | Updates | The license-bound appcast URL for paid apps. | | Language | File | Needs | Tested | | --- | --- | --- | --- | | TypeScript (Electron, Node 18+) | `typescript/appxi-signin.ts` | nothing | yes, against a mock AppsXi (`tests/signin-sdk.test.ts`) | | Swift (macOS 12+) | `swift/AppXiSignIn.swift` | Foundation, CryptoKit, IOKit, AppKit, Network, AuthenticationServices | yes, compiled (Swift 5 and 6 modes) and run against a mock AppsXi | | C++ / JUCE | `cpp/appxi_signin.hpp`, `.cpp` | OpenSSL 1.1.1+ (libcrypto); libcurl with `APPXI_USE_CURL`, or your own HTTP function | yes, compiled with clang and run against a mock AppsXi | | .NET 6+ | `dotnet/AppXiSignIn.cs` | BouncyCastle.Cryptography (Ed25519) | not yet compiled here (no .NET SDK on the build Mac) | Run the Swift and C++ tests with `tests/run-signin-tests.sh` (macOS, Node, Homebrew OpenSSL 3). ### Backend Kit (TypeScript) `typescript/appxi-kit.ts` adds remote config and feature flags, per-buyer storage, crash reports, usage counts, an AI proxy and announcements on top of `appxi-signin.ts`: `new AppXiKit(appxi, { appVersion })`. Tested against a mock AppsXi (`tests/kit-sdk.test.ts`). Other languages call the same HTTP endpoints; see https://appsxi.com/docs/backend-kit ## Level 1: license key helpers Each one does the same five things: | | | | --- | --- | | Validate | `activate(key)` validates online, takes a seat on this device and caches the signed token. | | Offline check | `current()` verifies the cached Ed25519 token with AppsXi's public key and its expiry. | | Trial status | `trialStatus()`: in trial, days left, expired. | | Checkout | `checkoutUrl` / `openCheckout()`: your AppsXi checkout. | | Update feed | The license-bound appcast URL for paid apps (Sparkle, WinSparkle, electron-updater). | | Language | File | Needs | Tested | | --- | --- | --- | --- | | TypeScript (Electron, Node 18+) | `typescript/appxi-license.ts` | nothing | yes, against a mock API (`tests/license-helper.test.ts`) | | Swift (macOS 12+) | `swift/AppXiLicense.swift` | Foundation, CryptoKit, IOKit, AppKit | yes, compiled and run against a mock API | | C++ / JUCE | `cpp/appxi_license.hpp`, `.cpp` | OpenSSL 1.1.1+ (libcrypto); libcurl with `APPXI_USE_CURL`, or your own HTTP function | yes, compiled with clang and run against a mock API | | .NET 6+ | `dotnet/AppXiLicense.cs` | BouncyCastle.Cryptography (Ed25519) | not yet compiled here (no .NET SDK on the build Mac) | ## Keys - **Product key:** `pk_test_…` for development (sandbox licenses only), `pk_live_…` for release builds. Safe to ship. - **Public key:** the `x` value from `https://appsxi.com/api/v1/licenses/public-key`. Embed it; pass two during a rotation. ## Device id Level 1 helpers send SHA-256 of `::`; Level 2 SDKs send SHA-256 of `::appxi-l2`: the Mac's `IOPlatformUUID` or Windows' `MachineGuid`. The raw id never leaves the machine. ## What to do with the result - `current()` returns an entitlement: unlock. - Empty and `needsRefresh()`: call `refresh()` when online; if the network is down, keep the app usable until the token's `exp` (up to 30 days). - `reason` `seat_limit`: ask the buyer to free a seat in their AppsXi library. - `revoked` (refund or chargeback) or `expired` (trial over): the helper forgets the key; show your locked or trial-over state and the checkout link.