Skip to main content

Nethereum.Siwe.Core

NuGet: Nethereum.Siwe.Core | Source: src/Nethereum.Siwe.Core/

Nethereum.Siwe.Core

Core models and utilities for Sign-In with Ethereum (EIP-4361). This package provides the SiweMessage model, message parsing, string building, and validation helpers used by both Nethereum.Siwe and downstream authentication providers.

Key Components

ClassPurpose
SiweMessageEIP-4361 message model with Domain, Address, Statement, URI, Nonce, expiration, and chain binding
SiweMessageParserParses a plain-text SIWE string back into a SiweMessage (regex and ABNF modes)
SiweMessageStringBuilderBuilds the canonical plain-text representation for signing

Usage

Build a SIWE message string

var message = new SiweMessage
{
Domain = "example.com",
Address = "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B",
Statement = "Sign in to Example",
Uri = "https://example.com",
Version = "1",
ChainId = "1"
};
message.SetIssuedAtNow();
message.SetExpirationTime(DateTime.UtcNow.AddMinutes(10));
message.SetNotBefore(DateTime.UtcNow);
message.Nonce = "randomnonce123";

string plainText = SiweMessageStringBuilder.BuildMessage(message);

Parse a SIWE message

Two parsing modes are available — regex-based (default) and ABNF-based:

var parsed = SiweMessageParser.Parse(plainText);
// parsed.Address, parsed.Domain, parsed.Nonce, etc.

// ABNF-based parser (stricter validation)
var parsedAbnf = SiweMessageParser.ParseUsingAbnf(plainText);

Validate timing

bool valid = message.HasMessageDateStartedAndNotExpired();
bool hasRequired = message.HasRequiredFields();

// Individual checks
bool started = message.HasMessageDateStarted();
bool expired = message.HasMessageDateExpired();

Compare messages

bool same = message.IsTheSame(otherMessage);

SiweMessage Properties

PropertyTypeDescription
DomainstringRFC 4501 DNS authority (e.g. "example.com")
AddressstringEIP-55 checksum Ethereum address
StatementstringHuman-readable assertion for the user to sign
UristringRFC 3986 URI of the resource requesting authentication
VersionstringMessage version (currently "1")
NoncestringRandomized token (8+ alphanumeric characters)
IssuedAtstringISO 8601 datetime when the message was created
ExpirationTimestringISO 8601 datetime when the message expires (optional)
NotBeforestringISO 8601 datetime before which the message is not valid (optional)
RequestIdstringSystem-specific identifier (optional)
ChainIdstringEIP-155 chain ID to bind authentication to a specific chain
ResourcesList<string>List of RFC 3986 URIs the user is authorizing (optional)

SIWE RECAP (EIP-5573)

The RECAP (Resource Capability) system extends SIWE messages with fine-grained capability-based authorization. Instead of blanket sign-in, users can authorize specific actions on specific resources.

Key RECAP Classes

ClassPurpose
SiweRecapMsgBuilderFluent builder for constructing RECAP-enabled SIWE messages
SiweRecapCapabilityRepresents a set of permitted actions with optional targets
SiweNamespaceValidated namespace identifier (e.g. "eip155", "https")
SiweRecapExtensionsExtension methods for checking permissions on SIWE messages

Build a RECAP message

var message = new SiweMessage
{
Domain = "example.com",
Address = "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B",
Uri = "https://example.com",
Version = "1",
ChainId = "1"
};

// Use the fluent builder to add capabilities
var recapMessage = SiweRecapMsgBuilder.Init(message)
.AddDefaultActions(
new SiweNamespace("eip155"),
new HashSet<string> { "sign", "send" })
.AddTargetActions(
new SiweNamespace("https"),
"https://api.example.com",
new HashSet<string> { "read", "write" })
.Build();

string messageToSign = SiweMessageStringBuilder.BuildMessage(recapMessage);

Check permissions

// Check if the signed message grants a specific permission
bool canWrite = recapMessage.HasPermissions(
new SiweNamespace("https"),
"https://api.example.com",
"write");

// Verify statement matches declared permissions
bool consistent = recapMessage.HasStatementMatchingPermissions();

Decode a RECAP resource URN

var capability = SiweRecapCapability.DecodeResourceUrn(resourceUrn);
bool hasAccess = capability.HasTargetPermission("https://api.example.com", "read");
bool hasDefault = capability.HasPermissionByDefault("sign");

Relationship to Other Packages

  • Nethereum.Siwe — Adds session/nonce management, signature verification, and user registration checks on top of these core models
  • Nethereum.UINethereumSiweAuthenticatorService orchestrates SIWE authentication in Blazor Server using this package