Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.mellowtel.com/llms.txt

Use this file to discover all available pages before exploring further.

Integrate Mellowtel into your Windows desktop application to allow users to share their unused internet bandwidth in exchange for rewards or premium features.
User consent is mandatory. The SDK throws an InvalidOperationException if you call StartAsync() without the user having opted in.

Prerequisites

  • A Mellowtel account and Integration ID from the dashboard. Each desktop app gets its own unique Integration ID.
  • .NET 10 SDK
  • Windows 10 or Windows 11
  • A .NET desktop application (Console, WPF, or Windows Forms)
Want to see a complete, real-world integration before wiring this into your own app? The mellowtel-pomodoro-windows WPF sample shows the full flow end-to-end: consent dialog, settings toggle, and background lifecycle.

Installation

Mellowtel for Windows ships on NuGet as Mellowtel.Win.

1. Install the Package

From your project directory:
dotnet add package Mellowtel.Win
Or add a PackageReference to your .csproj:
<PackageReference Include="Mellowtel.Win" Version="1.0.0" />

2. Add to Your Code

using MellowtelWin;

// Initialize Mellowtel with your Integration ID
var mellowtel = new Mellowtel("YOUR_INTEGRATION_ID", new MellowtelOptions
{
    PluginId = "your-app-id"
});

// If the user has already opted in, resume silently.
// If not, this is a no-op and returns false.
await mellowtel.StartIfOptedInAsync();

// First-time flow: show your consent UI, then opt in and start.
if (!mellowtel.GetOptInStatus() && ShowConsentDialog())
{
    mellowtel.OptIn();
    await mellowtel.StartAsync();
}

// On app shutdown
await mellowtel.StopAsync();
mellowtel.Dispose();
Replace YOUR_INTEGRATION_ID with the Integration ID from your Mellowtel dashboard, and set PluginId to a stable identifier for your app. ShowConsentDialog() is your own UI that returns true only when the user explicitly agrees. See User Consent below.

Configuration options

MellowtelOptions lets you tune a few things:
PropertyTypeDefaultDescription
PluginIdstring"mellowtel-win"Stable identifier for your app. Set this to something unique.
MaxDailyRateintBuilt-in defaultMax requests the SDK will handle per day.
DisableLogsbooltrueSet to false to enable SDK logs during development.

Examples by Application Type

using MellowtelWin;

class Program
{
    static async Task Main(string[] args)
    {
        using var mellowtel = new Mellowtel("YOUR_INTEGRATION_ID", new MellowtelOptions
        {
            PluginId = "your-app-id"
        });

        if (!mellowtel.GetOptInStatus())
        {
            Console.WriteLine("User must opt in before using this service.");
            return;
        }

        using var cts = new CancellationTokenSource();
        Console.CancelKeyPress += (s, e) => { e.Cancel = true; cts.Cancel(); };

        try
        {
            await mellowtel.StartAsync(cts.Token);
            Console.WriteLine("Mellowtel running. Press Ctrl+C to stop.");
            await Task.Delay(Timeout.Infinite, cts.Token);
        }
        catch (InvalidOperationException ex)
        {
            Console.WriteLine($"Cannot start: {ex.Message}");
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("Stopping...");
        }
        finally
        {
            await mellowtel.StopAsync();
        }
    }
}

Observing connection state

The Mellowtel instance exposes a ConnectionStateChanged event that fires whenever the underlying WebSocket to Mellowtel’s backend connects or disconnects. The WPF and Windows Forms examples above subscribe to it to drive a status indicator. The payload is a bool where true means connected and false means disconnected. The event fires on a background thread, so UI frameworks that enforce thread affinity must marshal updates onto the UI thread. In WPF use Dispatcher.Invoke, and in Windows Forms use Control.Invoke (both shown in the examples above).
About the WPF async void OnClosing pattern. The WPF example above uses protected override async void OnClosing, which is the simplest form but has a subtle issue: base.OnClosing(e) is called synchronously while StopAsync() is still awaiting, so the window can close before cleanup finishes. For most apps this is fine because the process exits immediately afterwards. If you need a guaranteed graceful shutdown (for example, to flush telemetry), follow the Microsoft-documented deferral pattern where you set e.Cancel = true, await your async work, and then close the window explicitly.

Displaying a consent dialog is mandatory. The SDK enforces this: StartAsync() throws an InvalidOperationException if the user has not opted in.
var mellowtel = new Mellowtel("YOUR_INTEGRATION_ID", new MellowtelOptions
{
    PluginId = "your-app-id"
});

if (!mellowtel.GetOptInStatus())
{
    var userAgreed = ShowConsentDialog(); // your custom dialog

    if (userAgreed)
        mellowtel.OptIn();
    else
        return; // user declined, do not start
}

try
{
    await mellowtel.StartAsync();
}
catch (InvalidOperationException ex)
{
    Console.WriteLine($"Error: {ex.Message}");
}
1

Explain what Mellowtel does

Use plain language. Example: “This app uses Mellowtel to share your unused internet bandwidth. This allows you to [benefit/feature]. You can opt out at any time in settings.”
2

Give users a clear choice

Include distinct Accept and Decline options.
3

Link to policies

Include links to the Terms of Service and Privacy Policy.
// Check current status
bool isOptedIn = mellowtel.GetOptInStatus();

// Opt out
if (userWantsToOptOut)
{
    mellowtel.OptOut();
    await mellowtel.StopAsync();
}

// Opt back in
if (userWantsToOptIn)
{
    mellowtel.OptIn();
    await mellowtel.StartAsync();
}
For richer UI (for example, showing when the user first opted in), GetOptInDetails() returns the opt-in status alongside the opt-in and opt-out timestamps:
var (isOptedIn, optInDate, optOutDate) = mellowtel.GetOptInDetails();

Troubleshooting

  1. Make sure your project targets .NET 10 or later. Mellowtel.Win requires net10.0.
  2. Clear the NuGet cache and restore:
dotnet nuget locals all --clear
dotnet restore
StartAsync() requires explicit consent. Call OptIn() after your consent dialog returns a positive result, then call StartAsync(). For silent resume on subsequent launches, use StartIfOptedInAsync() instead, which is a no-op when the user has not opted in.

Estimated time to complete: 10-15 minutes. If you need help or have feedback, contact us at info@mellowtel.com or join our Discord community.