.NET SDK
This guide will get you all set up with our .NET SDK to integrate the licensing part of Moonbase into your .NET based apps.
Getting started
Start by adding the NuGet package to your project:
dotnet package add Moonbase.Net
If you haven't already, create a product in the Moonbase app, and check out the Implementation guide to get the relevant cryptography keys, endpoints and configuration. An example configuration could look like this:
var licensing = LicensingFactory.CreateInstance(
opts =>
{
opts.LicenseStore = StorageType.File;
opts.Endpoint = new Uri("https://demo.moonbase.sh");
opts.ProductId = "demo-app";
opts.PublicKey = @"
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAutOqeUiPMgYjAwQ53CyKhJSqojr2bejce0CshQi9Hd8mNZbkoROx
oS56eIzehFSlX4YwHnF47AR1+fPOe7Q33Cgzd6d9xqksiMH7sWK2mADIlB66vZdW
uk3Me0UMB22Biy1RQbSRMivu79MxCofsympoL/5CFjJLd1u37kxjuRWVLjJS84Rr
3L2W7R7Exnno/giC+L/Dv711mjgstmtlAQm5ZINvFvoLA1eFTDs6nlCs3dpJSiq3
fsBUMT9FtudzS5As54jeT/8MB66fJJ0A1LQ/v5CW8ACQYseFSIoOKErD3xU7QLIJ
ERUn++6CVMPvZo67jVbTY+GCXYfW4gGVZQIDAQAB
-----END RSA PUBLIC KEY-----";
});
If you have custom domains enabled for your customer portal, use that instead of the moonbase.sh domain.
This snippet sets up an instance of the licensing client where you will find all the features described below.
The licensing
instance will come with three main features:
ILicenseStore
that handles license token persistence, either to file or in-memoryILicenseClient
which is a HTTP client built around the Moonbase licensing APIIDeviceIdResolver
which by default generates unique device fingerprints using a number of factors
Like described in activation flows, multiple activation flows are possible through Moonbase, and the .NET SDK supports them all. Let's take a look at how each would be implemented using the SDK.
Browser based activations
Using browser based activation is the recommended flow, and the easiest to get going with. To start, request an activation using the SDK:
var activationRequest = await licensing.Client.RequestActivation();
This activationRequest
contains a browser
URL that the customer can use to fulfill the request, so let's open a browser:
Process.Start(new ProcessStartInfo(activationRequest.Browser.ToString()) { UseShellExecute = true });
While the customer is activating the license or requesting a trial, we can poll for completion:
License? activation = null;
do
{
await Task.Delay(5000);
activation = await licensing.Client.GetRequestedActivation(activationRequest);
} while (activation == null);
As soon as the customer has fulfilled the request, a License
will be ready for us.
The Moonbase SDK will ensure any License
coming through the API client contains a valid signature, and matches the current device automatically.
Keep in mind that this license activation might be a full license, or a time-scoped trial.
To make sure the customer doesn't have to keep doing this, it's best to persist the license to disk:
await licensing.Store.StoreLocalLicense(activation);
That way you can easily add a check when your app starts, to see if you can skip product activation entirely:
var localLicense = await licensing.Store.LoadLocalLicense();
var validatedLicense = await licensing.Client.ValidateLicense(localLicense);
// License has been re-validated, store updated license for next check
await licensing.Store.StoreLocalLicense(validatedLicense);
In-App activations
If you prefer to not redirect customers to the browser, it's perfectly possible to keep the activation flow contained to the app you're building. For this you need to build your own UI interface to let the customer choose what they want to accomplish.
Starting a trial
If the user wishes to trial the product, and you have trials enabled in the Moonbase merchant app, then it's as simple as requesting a trial:
var trialLicense = await licensing.Client.RequestTrial();
// Also persist to store so we don't have to repeat this at next startup
await licensing.Store.StoreLocalLicense(trialLicense);
In the case that you have restricted trials to registered customers only, you need to sign the customer in, or sign them up first:
Authenticating customers
Signing in existing customers requires you to build a form to collect email address and password, and authenticate those:
var user = await licensing.Client.SignIn(email, password);
In the case the customer doesn't already have an account, you can also make them one using the SDK:
var user = await licensing.Client.Register(name, email, password);
By authenticating using either of these methods, the SDK will keep the authenticated credentials until the app stops.
That way you are free to call authenticated methods like the above .RequestTrial()
as the signed in customer.
Activating an owned license
This path requires an authenticated user, so make sure you've followed the above steps first. To request activation of an owned license, simply call the appropriate method:
var license = await licensing.Client.RequestLicense();
// Also persist to store so we don't have to repeat this at next startup
await licensing.Store.StoreLocalLicense(license);
Check for existing license on startup
As with the browser based activation flow, after you're received a license from the API, you should persist it to the license store. Whenever the app starts up again, be sure to check for existing licenses to avoid having to re-activate the product:
var localLicense = await licensing.Store.LoadLocalLicense();
var validatedLicense = await licensing.Client.ValidateLicense(localLicense);
// License has been re-validated, store updated license for next check
await licensing.Store.StoreLocalLicense(validatedLicense);
Offline activations
You might have customers that need to be able to activate devices without connection to the internet. To facilitate this, Moonbase signs all license tokens we issue with the unique signature of the device being activated. Since offline devices cannot transmit this device signature over the internet, the app needs to generate a device token. This device token contains the necessary information to generate a valid license token for offline activations, and can easily be exchanged for a license by the customer in the customer portal.
To start, generate a device token:
var bytes = await licensing.GenerateDeviceToken();
var path = Path.Combine(
Path.GetDirectoryName(Assembly.GetEntryAssembly().Location),
"device.dt");
await File.WriteAllBytesAsync(path, bytes);
The snippet above generates the token, and then writes the result to a device.dt
file.
You can change the file name, but keep the extension to ensure compatability with the customer portal interface.
It's up to you to provide the necessary instructions to the customer for how to upload the device token to your customer portal.
What customers receive when they upload the device token in the customer portal is a license.mb
file.
This file contains a valid offline activated license token that you can read in using the SDK:
var licenseBytes = await File.ReadAllBytesAsync(path);
var license = await licensing.ReadRawLicense(licenseBytes);
// License has been read, store license for next check
await licensing.Store.StoreLocalLicense(validatedLicense);
Keep in mind that this license will have a ActivationMethod
of Offline
, which means trying to re-validate the license is not necessary.