![]() |
VOOZH | about |
dotnet add package Nethereum.UI --version 6.1.0
NuGet\Install-Package Nethereum.UI -Version 6.1.0
<PackageReference Include="Nethereum.UI" Version="6.1.0" />
<PackageVersion Include="Nethereum.UI" Version="6.1.0" />Directory.Packages.props
<PackageReference Include="Nethereum.UI" />Project file
paket add Nethereum.UI --version 6.1.0
#r "nuget: Nethereum.UI, 6.1.0"
#:package Nethereum.UI@6.1.0
#addin nuget:?package=Nethereum.UI&version=6.1.0Install as a Cake Addin
#tool nuget:?package=Nethereum.UI&version=6.1.0Install as a Cake Tool
Common UI services and abstractions for building Ethereum frontend applications with Nethereum.
Nethereum.UI provides infrastructure components for building Ethereum-enabled user interfaces across web, desktop, and mobile platforms. It defines standard abstractions for wallet providers, authentication, and input validation that work consistently across Blazor, MAUI, Avalonia, Unity, and other .NET UI frameworks.
Key Features:
IEthereumHostProvider)Use Cases:
dotnet add package Nethereum.UI
Standard interface for Ethereum wallet providers (MetaMask, WalletConnect, built-in wallets, etc.):
public interface IEthereumHostProvider
{
// Provider metadata
string Name { get; }
bool Available { get; }
bool Enabled { get; }
// Selected account/network
string SelectedAccount { get; }
long SelectedNetworkChainId { get; }
// Multi-wallet support
bool MultipleWalletsProvider { get; }
bool MultipleWalletSelected { get; }
// Change events
event Func<string, Task> SelectedAccountChanged;
event Func<long, Task> NetworkChanged;
event Func<bool, Task> AvailabilityChanged;
event Func<bool, Task> EnabledChanged;
// Provider operations
Task<bool> CheckProviderAvailabilityAsync();
Task<IWeb3> GetWeb3Async();
Task<string> EnableProviderAsync();
Task<string> GetProviderSelectedAccountAsync();
Task<string> SignMessageAsync(string message);
}
Service for managing the currently selected wallet provider:
public class SelectedEthereumHostProviderService
{
public IEthereumHostProvider SelectedHost { get; }
public event Func<IEthereumHostProvider, Task> SelectedHostProviderChanged;
Task SetSelectedEthereumHostProvider(IEthereumHostProvider provider);
Task ClearSelectedEthereumHostProvider();
}
SIWE authentication service integrating with wallet providers:
public class NethereumSiweAuthenticatorService
{
public NethereumSiweAuthenticatorService(
SelectedEthereumHostProviderService selectedEthereumHostProviderService,
ISessionStorage sessionStorage);
string GenerateNewSiweMessage(SiweMessage siweMessage);
Task<SiweMessage> AuthenticateAsync(SiweMessage siweMessage);
void LogOut(SiweMessage siweMessage);
}
using Nethereum.UI;
using Nethereum.Web3.Accounts;
// Create built-in provider with private key
var provider = new NethereumHostProvider();
// Set RPC URL and detect chain ID
await provider.SetUrl("https://mainnet.infura.io/v3/YOUR-PROJECT-ID");
// Set account
var account = new Account("0xYOUR_PRIVATE_KEY");
provider.SetSelectedAccount(account);
// Get Web3 instance
var web3 = await provider.GetWeb3Async();
var balance = await web3.Eth.GetBalance.SendRequestAsync(provider.SelectedAccount);
using Nethereum.UI;
// Create selection service
var selectionService = new SelectedEthereumHostProviderService();
// Subscribe to provider changes
selectionService.SelectedHostProviderChanged += async (provider) =>
{
if (provider != null)
{
Console.WriteLine($"Provider changed to: {provider.Name}");
Console.WriteLine($"Account: {provider.SelectedAccount}");
Console.WriteLine($"Chain ID: {provider.SelectedNetworkChainId}");
}
else
{
Console.WriteLine("Provider disconnected");
}
};
// Set provider
await selectionService.SetSelectedEthereumHostProvider(metamaskProvider);
// Later: switch providers
await selectionService.SetSelectedEthereumHostProvider(walletConnectProvider);
// Disconnect
await selectionService.ClearSelectedEthereumHostProvider();
using Nethereum.UI;
var provider = new NethereumHostProvider();
// Subscribe to account changes
provider.SelectedAccountChanged += async (address) =>
{
Console.WriteLine($"Account changed to: {address}");
// Update UI, reload balances, etc.
var web3 = await provider.GetWeb3Async();
var balance = await web3.Eth.GetBalance.SendRequestAsync(address);
Console.WriteLine($"New account balance: {Web3.Convert.FromWei(balance)} ETH");
};
// Subscribe to network changes
provider.NetworkChanged += async (chainId) =>
{
Console.WriteLine($"Network changed to chain ID: {chainId}");
// Update UI, warn user, etc.
if (chainId != 1)
{
Console.WriteLine("Warning: Not connected to Ethereum mainnet");
}
};
// Set account (triggers event)
provider.SetSelectedAccount("0xPRIVATE_KEY");
// Change network (triggers event)
await provider.SetUrl("https://polygon-rpc.com");
using Nethereum.UI;
using Nethereum.Siwe.Core;
// Setup services
var providerService = new SelectedEthereumHostProviderService();
var authService = new NethereumSiweAuthenticatorService(
providerService,
sessionStorage);
// Set provider (MetaMask, WalletConnect, etc.)
await providerService.SetSelectedEthereumHostProvider(metamaskProvider);
// Create SIWE message
var siweMessage = new SiweMessage
{
Domain = "example.com",
Address = providerService.SelectedHost.SelectedAccount,
Uri = "https://example.com/login",
Version = "1",
ChainId = providerService.SelectedHost.SelectedNetworkChainId,
Nonce = Guid.NewGuid().ToString(),
IssuedAt = DateTime.UtcNow.ToString("o")
};
try
{
// Authenticate (prompts wallet to sign)
var authenticatedMessage = await authService.AuthenticateAsync(siweMessage);
Console.WriteLine("Authentication successful!");
Console.WriteLine($"Authenticated address: {authenticatedMessage.Address}");
// User is now authenticated
}
catch (Exception ex)
{
Console.WriteLine($"Authentication failed: {ex.Message}");
}
// Later: log out
authService.LogOut(siweMessage);
using FluentValidation;
using Nethereum.UI.Validation;
public class TransferRequest
{
public string ToAddress { get; set; }
public string Amount { get; set; }
public string PrivateKey { get; set; }
}
public class TransferRequestValidator : AbstractValidator<TransferRequest>
{
public TransferRequestValidator()
{
RuleFor(x => x.ToAddress)
.NotEmpty()
.IsEthereumAddress(); // Custom Ethereum address validation
RuleFor(x => x.Amount)
.NotEmpty()
.Must(BeValidNumber)
.WithMessage("Invalid amount");
RuleFor(x => x.PrivateKey)
.IsEthereumPrivateKey(); // Validates hex format and length (66 chars)
}
private bool BeValidNumber(string value)
{
return decimal.TryParse(value, out _);
}
}
// Usage
var validator = new TransferRequestValidator();
var request = new TransferRequest
{
ToAddress = "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
Amount = "0.5",
PrivateKey = "0x..." // 64 hex chars
};
var result = validator.Validate(request);
if (!result.IsValid)
{
foreach (var error in result.Errors)
{
Console.WriteLine($"{error.PropertyName}: {error.ErrorMessage}");
}
}
using System.ComponentModel.DataAnnotations;
using Nethereum.UI.Validation.Attributes;
public class WalletConnectionForm
{
[Required]
[EthereumAddress]
public string WalletAddress { get; set; }
[Required]
[Url]
public string RpcUrl { get; set; }
}
// Usage in ASP.NET Core / Blazor
var form = new WalletConnectionForm
{
WalletAddress = "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
RpcUrl = "https://mainnet.infura.io/v3/YOUR-PROJECT-ID"
};
var context = new ValidationContext(form);
var results = new List<ValidationResult>();
if (Validator.TryValidateObject(form, context, results, true))
{
Console.WriteLine("Form is valid");
}
else
{
foreach (var error in results)
{
Console.WriteLine(error.ErrorMessage);
}
}
using Nethereum.UI;
using System.Threading.Tasks;
public class MyCustomWalletProvider : IEthereumHostProvider
{
public string Name => "My Custom Wallet";
public bool Available { get; private set; }
public string SelectedAccount { get; private set; }
public long SelectedNetworkChainId { get; private set; }
public bool Enabled => Available && SelectedAccount != null;
public bool MultipleWalletsProvider => false;
public bool MultipleWalletSelected => false;
public event Func<string, Task> SelectedAccountChanged;
public event Func<long, Task> NetworkChanged;
public event Func<bool, Task> AvailabilityChanged;
public event Func<bool, Task> EnabledChanged;
public async Task<bool> CheckProviderAvailabilityAsync()
{
// Check if your wallet extension/app is available
Available = await CheckIfWalletIsInstalled();
await AvailabilityChanged?.Invoke(Available);
return Available;
}
public async Task<string> EnableProviderAsync()
{
// Request user permission to connect
SelectedAccount = await RequestAccountAccess();
await SelectedAccountChanged?.Invoke(SelectedAccount);
await EnabledChanged?.Invoke(true);
return SelectedAccount;
}
public Task<IWeb3> GetWeb3Async()
{
// Return Web3 instance connected to your wallet
return Task.FromResult(myWalletWeb3Instance);
}
public Task<string> GetProviderSelectedAccountAsync()
{
return Task.FromResult(SelectedAccount);
}
public async Task<string> SignMessageAsync(string message)
{
// Call your wallet's signing method
return await myWallet.SignMessageAsync(message);
}
private async Task<bool> CheckIfWalletIsInstalled() { /* ... */ }
private async Task<string> RequestAccountAccess() { /* ... */ }
}
using FluentValidation;
using Nethereum.UI.Validation;
public class ContractInteractionForm
{
public string ContractAddress { get; set; }
public string FunctionData { get; set; }
public string RpcEndpoint { get; set; }
}
public class ContractInteractionValidator : AbstractValidator<ContractInteractionForm>
{
public ContractInteractionValidator()
{
RuleFor(x => x.ContractAddress)
.IsEthereumAddress()
.WithMessage("Please provide a valid Ethereum contract address");
RuleFor(x => x.FunctionData)
.IsHex()
.WithMessage("Function data must be valid hexadecimal with 0x prefix");
RuleFor(x => x.RpcEndpoint)
.IsUri()
.WithMessage("Please provide a valid RPC endpoint URL");
}
}
using Nethereum.UI.Validation;
// Ethereum address validation
RuleFor(x => x.Address).IsEthereumAddress();
// Hexadecimal data validation (must have 0x prefix)
RuleFor(x => x.Data).IsHex();
// Private key validation (0x + 64 hex chars = 66 total)
RuleFor(x => x.PrivateKey).IsEthereumPrivateKey();
// URI validation
RuleFor(x => x.Url).IsUri();
using Nethereum.UI.Validation.Attributes;
[EthereumAddress]
public string Address { get; set; }
[Hex]
public string Data { get; set; }
public interface IEthereumHostProvider
{
// Properties
string Name { get; }
bool Available { get; }
string SelectedAccount { get; }
long SelectedNetworkChainId { get; }
bool Enabled { get; }
bool MultipleWalletsProvider { get; }
bool MultipleWalletSelected { get; }
// Events
event Func<string, Task> SelectedAccountChanged;
event Func<long, Task> NetworkChanged;
event Func<bool, Task> AvailabilityChanged;
event Func<bool, Task> EnabledChanged;
// Methods
Task<bool> CheckProviderAvailabilityAsync();
Task<IWeb3> GetWeb3Async();
Task<string> EnableProviderAsync();
Task<string> GetProviderSelectedAccountAsync();
Task<string> SignMessageAsync(string message);
}
Built-in provider for testing and development:
public class NethereumHostProvider : IEthereumHostProvider
{
void SetSelectedAccount(string privateKey);
void SetSelectedAccount(Account account);
Task<bool> SetUrl(string url);
}
public class SelectedEthereumHostProviderService
{
public IEthereumHostProvider SelectedHost { get; }
public event Func<IEthereumHostProvider, Task> SelectedHostProviderChanged;
public Task SetSelectedEthereumHostProvider(IEthereumHostProvider provider);
public Task ClearSelectedEthereumHostProvider();
}
public class NethereumSiweAuthenticatorService
{
public NethereumSiweAuthenticatorService(
SelectedEthereumHostProviderService selectedEthereumHostProviderService,
ISessionStorage sessionStorage);
public string GenerateNewSiweMessage(SiweMessage siweMessage);
public Task<SiweMessage> AuthenticateAsync(SiweMessage siweMessage);
public void LogOut(SiweMessage siweMessage);
}
The IEthereumHostProvider interface follows this lifecycle:
CheckProviderAvailabilityAsync() - Check if wallet is installed/availableEnableProviderAsync() - Request user permission to connectSelectedAccount and fires SelectedAccountChanged eventGetWeb3Async() returns configured Web3 instanceSignMessageAsync() for SIWE and other signature requestsAll provider change events are async:
provider.SelectedAccountChanged += async (account) =>
{
// Async operations allowed
await UpdateUserInterface(account);
};
Some providers (like WalletConnect with multiple sessions) support multiple simultaneous wallet connections:
if (provider.MultipleWalletsProvider)
{
Console.WriteLine("This provider supports multiple wallets");
if (provider.MultipleWalletSelected)
{
Console.WriteLine("Multiple wallets are currently connected");
}
}
Nethereum.UI provides validation through two approaches:
Choose based on your target framework and preferences.
SIWE authentication requires:
ISessionStorage)| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 net5.0 was computed. net5.0-windows net5.0-windows was computed. net6.0 net6.0 is compatible. net6.0-android net6.0-android was computed. net6.0-ios net6.0-ios was computed. net6.0-maccatalyst net6.0-maccatalyst was computed. net6.0-macos net6.0-macos was computed. net6.0-tvos net6.0-tvos was computed. net6.0-windows net6.0-windows was computed. net7.0 net7.0 was computed. net7.0-android net7.0-android was computed. net7.0-ios net7.0-ios was computed. net7.0-maccatalyst net7.0-maccatalyst was computed. net7.0-macos net7.0-macos was computed. net7.0-tvos net7.0-tvos was computed. net7.0-windows net7.0-windows was computed. net8.0 net8.0 is compatible. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 is compatible. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 netcoreapp2.0 was computed. netcoreapp2.1 netcoreapp2.1 was computed. netcoreapp2.2 netcoreapp2.2 was computed. netcoreapp3.0 netcoreapp3.0 was computed. netcoreapp3.1 netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 netstandard2.0 is compatible. netstandard2.1 netstandard2.1 was computed. |
| .NET Framework | net461 net461 was computed. net462 net462 was computed. net463 net463 was computed. net47 net47 was computed. net471 net471 was computed. net472 net472 is compatible. net48 net48 was computed. net481 net481 was computed. |
| MonoAndroid | monoandroid monoandroid was computed. |
| MonoMac | monomac monomac was computed. |
| MonoTouch | monotouch monotouch was computed. |
| Tizen | tizen40 tizen40 was computed. tizen60 tizen60 was computed. |
| Xamarin.iOS | xamarinios xamarinios was computed. |
| Xamarin.Mac | xamarinmac xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos xamarinwatchos was computed. |
Showing the top 5 NuGet packages that depend on Nethereum.UI:
| Package | Downloads |
|---|---|
|
Nethereum.Metamask
Nethereum.Metamask Nethereum Metamask core integration |
|
|
Nethereum.WalletConnect
Nethereum.WalletConnect Nethereum WalletConnect integration |
|
|
Nethereum.EIP6963WalletInterop
Nethereum.EIP6963WalletInterop Nethereum EIP6963 Browser Wallet Extension Interop, core components to integrate with browser extensions like Metamask, Coinbase, Brave, Rabby, Rainbow, and many more see https://eips.ethereum.org/EIPS/eip-6963 and https://eip6963.org/ |
|
|
Nethereum.Blazor
Nethereum.Blazor Nethereum integration with Blazor including EIP6963WalletInterop and EthereumAuthenticationProvider |
|
|
Nethereum.Wallet
Core wallet services for managing accounts, vaults, and configuration across the Nethereum stack. |
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 6.1.0 | 1,804 | 3/25/2026 |
| 6.0.4 | 478 | 3/18/2026 |
| 6.0.3 | 416 | 3/18/2026 |
| 6.0.1 | 476 | 3/17/2026 |
| 6.0.0 | 450 | 3/16/2026 |
| 5.8.0 | 923 | 1/6/2026 |
| 5.0.0 | 1,242 | 5/28/2025 |
| 4.29.0 | 682 | 2/10/2025 |
| 4.28.0 | 492 | 1/7/2025 |
| 4.27.1 | 389 | 12/24/2024 |
| 4.27.0 | 362 | 12/24/2024 |
| 4.26.0 | 589 | 10/1/2024 |
| 4.25.0 | 460 | 9/19/2024 |
| 4.21.4 | 1,430 | 8/9/2024 |
| 4.21.3 | 547 | 7/22/2024 |
| 4.21.2 | 645 | 6/26/2024 |
| 4.21.1 | 383 | 6/26/2024 |
| 4.21.0 | 784 | 6/18/2024 |
| 4.20.0 | 2,184 | 3/28/2024 |
| 4.19.0 | 763 | 2/16/2024 |