IronLicensing SDK for Go
Go to file
David Friedel 14cf80348c Remove promotional links from README 2025-12-26 11:41:22 +00:00
.gitignore Implement IronLicensing Go SDK 2025-12-25 11:21:32 +00:00
LICENSE Initial commit 2025-12-25 04:58:35 -05:00
README.md Remove promotional links from README 2025-12-26 11:41:22 +00:00
client.go Implement IronLicensing Go SDK 2025-12-25 11:21:32 +00:00
config.go Implement IronLicensing Go SDK 2025-12-25 11:21:32 +00:00
go.mod Implement IronLicensing Go SDK 2025-12-25 11:21:32 +00:00
transport.go Implement IronLicensing Go SDK 2025-12-25 11:21:32 +00:00
types.go Implement IronLicensing Go SDK 2025-12-25 11:21:32 +00:00

README.md

IronLicensing Go SDK

Software licensing and activation SDK for Go applications. Validate licenses, manage activations, check features, and handle trials.

Installation

go get github.com/IronServices/ironlicensing-go

Quick Start

Using Global Client

package main

import (
    "fmt"
    "log"

    licensing "github.com/IronServices/ironlicensing-go"
)

func main() {
    // Initialize the global client
    err := licensing.Init("pk_live_your_public_key", "your-product-slug")
    if err != nil {
        log.Fatal(err)
    }

    // Validate a license
    result := licensing.Validate("IRON-XXXX-XXXX-XXXX-XXXX")
    if result.Valid {
        fmt.Println("License is valid!")
        fmt.Printf("Status: %s\n", result.License.Status)
    } else {
        fmt.Printf("Validation failed: %s\n", result.Error)
    }

    // Check for features
    if licensing.HasFeature("premium") {
        fmt.Println("Premium features enabled!")
    }
}

Using Client Instance

package main

import (
    "context"
    "fmt"
    "log"

    licensing "github.com/IronServices/ironlicensing-go"
)

func main() {
    client, err := licensing.NewClient(licensing.Options{
        PublicKey:   "pk_live_your_public_key",
        ProductSlug: "your-product-slug",
        Debug:       true,
    })
    if err != nil {
        log.Fatal(err)
    }

    // Activate with context
    ctx := context.Background()
    result := client.ActivateContext(ctx, "IRON-XXXX-XXXX-XXXX-XXXX", "My Machine")

    if result.Valid {
        fmt.Printf("Activated! License type: %s\n", result.License.Type)
    }
}

Configuration

options := licensing.Options{
    PublicKey:              "pk_live_xxx",           // Required
    ProductSlug:            "your-product",          // Required
    APIBaseURL:             "https://api.ironlicensing.com", // Default
    Debug:                  false,                   // Enable debug logging
    EnableOfflineCache:     true,                    // Cache for offline use
    CacheValidationMinutes: 60,                      // Cache duration
    OfflineGraceDays:       7,                       // Offline grace period
    HTTPTimeout:            30 * time.Second,        // Request timeout
}

Functional Options

err := licensing.Init("pk_live_xxx", "product-slug",
    licensing.WithDebug(true),
)

License Validation

// Simple validation
result := client.Validate("IRON-XXXX-XXXX-XXXX-XXXX")

// With context for timeout/cancellation
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
result := client.ValidateContext(ctx, "IRON-XXXX-XXXX-XXXX-XXXX")

if result.Valid {
    license := result.License
    fmt.Printf("License: %s\n", license.Key)
    fmt.Printf("Status: %s\n", license.Status)
    fmt.Printf("Type: %s\n", license.Type)
    fmt.Printf("Activations: %d/%d\n", license.CurrentActivations, license.MaxActivations)
}

License Activation

// Simple activation (uses hostname as machine name)
result := client.Activate("IRON-XXXX-XXXX-XXXX-XXXX")

// With custom machine name
result := client.ActivateContext(ctx, "IRON-XXXX-XXXX-XXXX-XXXX", "Production Server")

if result.Valid {
    fmt.Println("License activated successfully!")

    // View activations
    for _, activation := range result.Activations {
        fmt.Printf("- %s (%s)\n", activation.MachineName, activation.Platform)
    }
}

License Deactivation

if client.Deactivate() {
    fmt.Println("License deactivated from this machine")
}

Feature Checking

// Check if feature is available
if client.HasFeature("advanced-analytics") {
    // Enable advanced analytics
}

// Require feature (returns error if not available)
if err := client.RequireFeature("export-pdf"); err != nil {
    fmt.Printf("Feature not available: %v\n", err)
    return
}

// Get feature details
feature := client.GetFeature("max-users")
if feature != nil {
    fmt.Printf("Feature: %s - %s\n", feature.Name, feature.Description)
}

Trial Management

result := client.StartTrial("user@example.com")
if result.Valid {
    fmt.Println("Trial started!")
    fmt.Printf("Trial key: %s\n", result.License.Key)
    if result.License.ExpiresAt != nil {
        fmt.Printf("Expires: %s\n", result.License.ExpiresAt.Format(time.RFC3339))
    }
}

In-App Purchase

// Get available tiers
tiers := client.GetTiers()
for _, tier := range tiers {
    fmt.Printf("%s - $%.2f %s\n", tier.Name, tier.Price, tier.Currency)
}

// Start checkout
checkout := client.StartPurchase("tier-id", "user@example.com")
if checkout.Success {
    fmt.Printf("Checkout URL: %s\n", checkout.CheckoutURL)
    // Open URL in browser for user to complete purchase
}

License Status

// Get current license
license := client.License()
if license != nil {
    fmt.Printf("Licensed to: %s\n", license.Email)
}

// Check status
status := client.Status()
switch status {
case licensing.StatusValid:
    fmt.Println("License is valid")
case licensing.StatusExpired:
    fmt.Println("License has expired")
case licensing.StatusTrial:
    fmt.Println("Running in trial mode")
case licensing.StatusNotActivated:
    fmt.Println("No license activated")
default:
    fmt.Printf("Status: %s\n", status)
}

// Quick checks
if client.IsLicensed() {
    fmt.Println("Application is licensed")
}

if client.IsTrial() {
    fmt.Println("Running in trial mode")
}

License Types

Type Description
TypePerpetual One-time purchase, never expires
TypeSubscription Recurring payment, expires if not renewed
TypeTrial Time-limited trial license

License Statuses

Status Description
StatusValid License is valid and active
StatusExpired License has expired
StatusSuspended License temporarily suspended
StatusRevoked License permanently revoked
StatusTrial Active trial license
StatusTrialExpired Trial period ended
StatusNotActivated No license activated

Thread Safety

The client is thread-safe and can be used concurrently from multiple goroutines:

var wg sync.WaitGroup
for i := 0; i < 10; i++ {
    wg.Add(1)
    go func() {
        defer wg.Done()
        if client.HasFeature("concurrent-feature") {
            // Safe to call from multiple goroutines
        }
    }()
}
wg.Wait()

Error Handling

// Validation errors
result := client.Validate(licenseKey)
if !result.Valid {
    switch result.Error {
    case "license_not_found":
        fmt.Println("Invalid license key")
    case "license_expired":
        fmt.Println("Your license has expired")
    case "max_activations_reached":
        fmt.Println("No more activations available")
    default:
        fmt.Printf("Error: %s\n", result.Error)
    }
}

// Feature requirement errors
err := client.RequireFeature("premium")
if err != nil {
    if lre, ok := err.(*licensing.LicenseRequiredError); ok {
        fmt.Printf("Feature '%s' requires a valid license\n", lre.Feature)
    }
}

Machine ID

The SDK automatically generates and persists a unique machine ID at ~/.ironlicensing/machine_id. This ID is used for:

  • Tracking activations per machine
  • Preventing license sharing
  • Offline validation

License

MIT License - see LICENSE file for details.