Licensing
Licensing is eligibility layered on an entitlement. The purchase must provide both the entitlement and its license eligibility.
import { Access, Licensing } from "@byfungsi/sapa";import { Effect } from "effect";
const benefits = Effect.all([ Access.entitlements({ entitlements: ["desktop.use"], duration: "perpetual", }), Licensing.eligibility({ entitlement: "desktop.use", activationLimit: 3, }),]);Issue and activate
Section titled “Issue and activate”import { activateLicenseCredential, issueLicenseCredential, LicenseCredentialIssuance,} from "@byfungsi/sapa";import { Effect } from "effect";
const program = Effect.gen(function* () { const issuance = yield* issueLicenseCredential({ idempotencyKey: "customer-42-desktop-license", externalCustomerId: "customer-42", entitlement: "desktop.use", });
if (!LicenseCredentialIssuance.guards.issued(issuance)) return issuance;
const activation = yield* activateLicenseCredential({ key: issuance.key, activationId: "device-7f50d6c8", });
return { issuance, activation };});The raw key is returned only for the first accepted issuance. An exact or later
issuance returns already_issued without the key. Deliver and store the first
key securely; SAPA persists a verifier, not the raw key.
Validate online
Section titled “Validate online”Call validateLicenseCredential({ key, activationId }). A successful operation
returns either valid or an invalid reason. Infrastructure failures remain in
the typed error channel and must fail closed.
Lifecycle operations
Section titled “Lifecycle operations”deactivateLicenseCredentialterminally ends one activation.revokeLicenseCredentialterminally revokes a credential bylicenseId.rotateLicenseCredentialinvalidates the old key and returns the new key only on the first accepted rotation.
Never log raw keys, include them in errors, save them in analytics, or return them again from a retry path.