Veriqa.Core.ChannelAdapter 0.6.1

Prefix Reserved
dotnet add package Veriqa.Core.ChannelAdapter --version 0.6.1
                    
NuGet\Install-Package Veriqa.Core.ChannelAdapter -Version 0.6.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Veriqa.Core.ChannelAdapter" Version="0.6.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Veriqa.Core.ChannelAdapter" Version="0.6.1" />
                    
Directory.Packages.props
<PackageReference Include="Veriqa.Core.ChannelAdapter" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Veriqa.Core.ChannelAdapter --version 0.6.1
                    
#r "nuget: Veriqa.Core.ChannelAdapter, 0.6.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Veriqa.Core.ChannelAdapter@0.6.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Veriqa.Core.ChannelAdapter&version=0.6.1
                    
Install as a Cake Addin
#tool nuget:?package=Veriqa.Core.ChannelAdapter&version=0.6.1
                    
Install as a Cake Tool

Veriqa.Core.ChannelAdapter

The channel contour of Veriqa: the registration SPI every channel plugs into, the webhook pipeline and the settings resolution seam. The channels themselves — the ones shipped with the product and a third-party one alike — live in their own packages and bring their own platform SDK, so this package depends on no channel platform at all.

Packages

Two ways to install the channels, and both are ordinary NuGet:

# the base set in one package: Telegram, WhatsApp, Email (plus this contour)
dotnet add package Veriqa.Core.BaseChannels
# MAX is deliberately outside the metapackage — install it explicitly when you need it
dotnet add package Veriqa.Core.ChannelAdapter.Max

# or take only the channel you actually use — nothing else arrives with it
dotnet add package Veriqa.Core.ChannelAdapter.Email
Package Contents Platform dependency
Veriqa.Core.ChannelAdapter the contour: AddChannel, the webhook pipeline, channel settings none
Veriqa.Core.ChannelAdapter.Telegram the Telegram channel Telegram.Bot
Veriqa.Core.ChannelAdapter.WhatsApp the WhatsApp channel (Meta Cloud API) none — plain HTTP
Veriqa.Core.ChannelAdapter.Max the MAX channel Max.BotClient
Veriqa.Core.ChannelAdapter.Email the Email channel MailKit, QRCoder
Veriqa.Core.ChannelAdapter.Redis Redis-backed channel stores (multiple replicas) StackExchange.Redis
Veriqa.Core.BaseChannels metapackage: the contour + Telegram, WhatsApp, Email —

Veriqa.Core.AuthServer depends on the contour only, so no channel library reaches a host through it: a deployment that signs users in through Telegram alone never receives a mail library. Installing both the metapackage and a separate channel is fine — NuGet resolves it to one copy.

Registration

The registration call does not change with the package it arrives from: every Add* is an extension method in this assembly's own namespace.

Register the adapters through the AuthServer facade:

authServer.AddChannelAdapters(adapters =>
{
    adapters.AddTelegram();  // Telegram channel
    adapters.AddWhatsApp();  // WhatsApp channel
    adapters.AddMax();       // MAX channel
    adapters.AddEmail();     // Email channel (magic-link)
});

Replacing a shipped implementation

The shipped implementations of the public channel ports — IEmailActionTokenStore, IEmailOutboundSender, IWhatsAppProvider — are registered with TryAddSingleton, so your registration always wins over the built-in default and the result does not depend on call order:

// 1. A plain registration made before AddVeriqaChannelAdapters (directly or through
//    AddVeriqaAuthServer, which calls it): yours is already in the collection, so the
//    shipped default is not added at all.
builder.Services.AddSingleton<IEmailActionTokenStore, MyActionTokenStore>();
builder.Services.AddVeriqaAuthServer(configuration, environment, authServer =>
    authServer.AddChannelAdapters(adapters => adapters.AddEmail()));

// 2. RemoveAll + Add after AddVeriqa* — still supported, unchanged.
builder.Services.RemoveAll<IEmailActionTokenStore>();
builder.Services.AddSingleton<IEmailActionTokenStore, MyActionTokenStore>();

This is the same discipline the AuthServer extension points follow — see Veriqa.Core.AuthServer/README.md, "Substitution does not depend on call order".

A port consumed as IEnumerable<T> is not covered by this: IChannelAdapter collects every registration rather than picks one, so a host adds to it with a plain registration and replaces nothing.

Neither is an explicitly requested implementation: UseRedisChannelStores (see "Multiple replicas") registers its three stores unconditionally, precisely so that it beats the TryAdd-ed defaults in either call order. A host that wants its own store of one of those ports while using the satellite replaces it with RemoveAll + Add after the call.

Multiple replicas

The contour keeps three stores of its own, and their shipped implementations are in-process: IChannelPromptMessageStore (coordinates of the in-channel prompt already sent), IEmailActionTokenStore and IEmailPushCorrelationStore (the Email channel's Pull tokens, Push correlations and inbound-mail deduplication). One replica is fine. Two are not: a magic link opened on replica B finds no token minted on replica A, an inbound email is not matched to its transaction, and a prompt is not edited on expiry when the event lands on the other instance.

Deploying more than one replica — install the Redis satellite and wire all three ports with one call:

dotnet add package Veriqa.Core.ChannelAdapter.Redis
authServer.AddChannelAdapters(adapters =>
{
    adapters.AddEmail();

    adapters.UseRedisChannelStores(redis =>
    {
        // Leave empty to reuse an IConnectionMultiplexer already registered in the container.
        redis.Configuration = "localhost:6379";
    });
});

Unlike the shipped defaults, these three registrations are unconditional, so the result does not depend on whether the call comes before or after AddEmail(). Without the call nothing changes — the in-process defaults stay. Setting Configuration while another component registers a non-keyed IConnectionMultiplexer stops the host at start-up with an error naming both connections by their endpoints, logical database, TLS settings and sentinel master name (credentials are never printed), rather than quietly sending the channel stores to the other Redis. The check runs when the host starts, so it holds whichever of the two registrations came first.

Key prefixes and the deduplication window are RedisChannelStoreOptions; record lifetimes are not, because they belong to the stored entity — a token and a correlation live until their own ExpiresAt, prompt coordinates until the longest transaction the engine can create has expired and the expiry event that consumes them has had time to be published.

Supported channels

Channel Delivery Notes
Telegram Bot API (webhook or long polling) Full support.
MAX Bot API (webhook or long polling) Full support.
WhatsApp Meta Cloud API The shipped provider; a custom one can be registered.
Email SMTP or a custom sender (via DI) Magic-link delivery, not a pushed prompt.

A third-party channel is registered exactly the same way — through AddChannel on the same builder; see the custom channel adapter guide. Nothing in this package treats a shipped channel differently from one you wrote.

WhatsApp: the shipped provider and a custom one

WhatsApp delivery ships with the Meta Cloud API provider, and it is the only one in the box. A host plugs its own delivery provider with UseWhatsAppProvider<TProvider>() on the channel adapter builder — before or after AddWhatsApp(), the last call wins. A provider names itself with a code (WhatsAppProviderNames holds the shipped ones), and Veriqa:Channels:WhatsApp:Provider declares the code the installation expects. The two are compared at startup: a mismatch stops the host with an error naming both codes, so the declared and the actual delivery path never diverge silently.

Webhook signature validation stays specific to the Meta Cloud API — a custom provider gets working delivery and a webhook that the adapter rejects.

Email

The email channel delivers a magic-link email rather than a pushed confirmation prompt, so the generic push/webhook adapter methods do not apply to it. Its inbound and outbound flows use the dedicated email endpoints and the SMTP or custom outbound sender. Currently supported outbound providers are Smtp and Custom (registered via DI).

License

Mozilla Public License 2.0 — see the LICENSE file in the repository root; the package carries the MPL-2.0 license expression in its metadata.


Veriqa™ — © Dmitrii Erusov. Sources and mirrors: https://veriqa.app · devs@veriqa.app

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (7)

Showing the top 5 NuGet packages that depend on Veriqa.Core.ChannelAdapter:

Package Downloads
Veriqa.Core.AuthServer

OpenID Connect provider for ASP.NET Core built on OpenIddict: passwordless sign-in and action approval through messaging apps, on any device. On a computer, TV or kiosk, your users scan a QR code shown by your website or app. On a phone, they tap a button. Either way, they confirm with one tap in Telegram, WhatsApp or another messenger they already have.

Veriqa.Core.BaseChannels

Veriqa base channel set — a metapackage pulling the channel contour together with the Telegram, WhatsApp and Email channels. Other channels ship as separate packages.

Veriqa.Core.ChannelAdapter.Email

Passwordless OpenID Connect sign-in by email for ASP.NET Core (OpenIddict): a magic link with a QR code, or the one-tap email — the user sends a pre-filled letter with one tap, nothing to type. Over SMTP and an inbound provider; for users without a messenger. Veriqa channel adapter (satellite package).

Veriqa.Core.ChannelAdapter.WhatsApp

Passwordless OpenID Connect sign-in and action approval through WhatsApp for ASP.NET Core (OpenIddict), over the Meta Cloud API. Users scan a QR code on a computer, TV or kiosk, or tap a button on the phone, and confirm with one tap in WhatsApp. Veriqa channel adapter (satellite package).

Veriqa.Core.ChannelAdapter.Telegram

Passwordless OpenID Connect sign-in and action approval through Telegram for ASP.NET Core (OpenIddict). Users scan a QR code on a computer, TV or kiosk, or tap a button on the phone, and confirm with one tap in Telegram. Veriqa channel adapter (satellite package).

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.6.1 174 10/7/2026
0.6.0 195 9/23/2026