Celebrating 10 years of .NET Ethereum integration! (November 2015 - November 2025)
This release marks a major milestone with comprehensive new libraries for Light Client verification, enterprise wallet infrastructure, hardware wallet integration, and DeFi protocol support.
119 commits since 5.0.0 | 23+ new libraries | Significant updates to existing packages
A complete light client implementation enabling trustless Ethereum state verification without running a full node. This is a major milestone for Nethereum, allowing applications to cryptographically verify balances, storage, and contract state using the Beacon Chain consensus layer.
HTTP client for the Beacon Chain REST API (Ethereum consensus layer).
- BeaconApiClient - Main API client with configurable endpoints
- ILightClientApi - Light client specific API endpoints:
GetBootstrapAsync()- Fetch initial checkpoint dataGetUpdatesAsync()- Period-based update fetchesGetFinalityUpdateAsync()- Latest finalized stateGetOptimisticUpdateAsync()- Latest optimistic header
- LightClientResponseMapper - Maps HTTP responses to domain objects with hex string conversions
Beacon chain light client implementation for trustless state verification.
// Initialize light client with Beacon API
var beaconClient = new BeaconApiClient("https://beacon-api.example.com");
var lightClientApi = new LightClientApiClient(beaconClient);
var blsSigner = new HerumiNativeBindings();
await blsSigner.EnsureAvailableAsync();
var config = new LightClientConfig
{
GenesisValidatorsRoot = genesisRoot,
CurrentForkVersion = forkVersion,
WeakSubjectivityRoot = checkpointRoot,
SlotsPerEpoch = 32,
SecondsPerSlot = 12
};
var lightClient = new LightClientService(lightClientApi, blsSigner, config, store);
await lightClient.InitializeAsync();
// Update to latest finalized state
await lightClient.UpdateAsync();
// Or use optimistic updates for faster tracking
await lightClient.UpdateOptimisticAsync();Key Features:
- Three update modes: Finality (most secure), Optimistic (fastest), Standard
- Sync committee verification via BLS aggregate signatures
- Merkle proof validation for execution and finality branches
- Block hash tracking for up to 256 recent blocks
- Persistent state via
ILightClientStoreabstraction
Commits: 2b21ec00, 7fd890cf, 093d2836
Ethereum 2.0 consensus layer domain objects with SSZ (Simple Serialize) encoding/decoding.
Beacon Chain Types:
BeaconBlockHeader- Slot, proposer index, parent/state/body rootsExecutionPayloadHeader- Block metadata, state root, gas metrics, blob gasSyncAggregate- 64-byte participation bitmap + 96-byte aggregate signatureSyncCommittee- 512 public keys + aggregate key
Light Client Messages:
LightClientBootstrap- Initial checkpoint with sync committeeLightClientUpdate- Period updates with signaturesLightClientFinalityUpdate- Finalized header with proofsLightClientOptimisticUpdate- Latest header tracking
Hash Tree Root Support:
SszBasicTypes.HashTreeRoot()for all consensus types- Merkle tree depth constants and generalized indices
- Support for Deneb and Electra fork differences
Commits: 89541e37, a62fa294, fef498c8
Core SSZ (Simple Serialize) infrastructure for Ethereum 2.0.
// SSZ Serialization
var writer = new SszWriter(buffer);
writer.WriteUInt64(slot);
writer.WriteBytes32(parentRoot);
writer.WriteBytes32(stateRoot);
// SSZ Deserialization
var reader = new SszReader(data);
var slot = reader.ReadUInt64();
var parentRoot = reader.ReadBytes32();
// Merkle Proof Verification
var isValid = SszMerkleizer.VerifyProof(
root: stateRoot,
leaf: leafHash,
proof: proofBranches,
generalizedIndex: index
);Components:
- SszWriter - Efficient serialization with little-endian encoding
- SszReader - Ref struct deserializer with bounds checking
- SszMerkleizer - SHA-256 Merkleization with proof verification
Commits: e69092c4, 58a7a8bc, 88ddeeae
Cryptographic verification of execution layer state against light client consensus.
// Create verified state service
var verifiedService = new VerifiedStateService(lightClient, evmService, proofVerifier);
// Get cryptographically verified balance
var balance = await verifiedService.GetBalanceAsync("0x...");
// Get verified storage slot
var storage = await verifiedService.GetStorageAtAsync(contractAddress, slot);
// Get verified account (balance, nonce, code hash, storage root)
var account = await verifiedService.GetAccountAsync("0x...");Transparent RPC Interception:
// Add verified state interceptor to Web3
var interceptor = new VerifiedStateInterceptor(verifiedService);
interceptor.FallbackOnError = true;
interceptor.FallbackTriggered += (s, e) => Console.WriteLine($"Fallback: {e.Reason}");
var web3 = new Web3(rpcClient);
web3.Client.OverridingRequestInterceptor = interceptor;
// All eth_getBalance, eth_getCode, eth_getStorageAt calls
// are now verified against the light client!
var balance = await web3.Eth.GetBalance.SendRequestAsync("0x...");Verified Methods:
eth_getBalance- Account balance with proofeth_getTransactionCount- Nonce with proofeth_getCode- Contract bytecode with proofeth_getStorageAt- Storage slot with proofeth_blockNumber- Current verified block
Caching:
VerifiedStateCacheandVerifiedAccountStateminimize round-trips- Configurable verification modes
Commits: b8305a7f, f8e60d87, e3b37c4a
Abstract BLS (Boneh-Lynn-Shacham) signature verification interface for Ethereum 2.0 consensus.
public interface IBls
{
bool VerifyAggregate(
byte[][] publicKeys,
byte[][] messages,
byte[] signature
);
}- Pluggable architecture - Supports native and managed implementations
- IBlsEnvironment - Runtime implementation detection
- NativeBls - Wrapper with lazy initialization
Production BLS implementation using Herumi/MCL library - high-performance native C++ bindings.
var bls = new HerumiNativeBindings();
await bls.EnsureAvailableAsync();
// Verify aggregated sync committee signatures
var isValid = bls.VerifyAggregate(
publicKeys: syncCommitteeKeys,
messages: new[] { signingRoot },
signature: aggregateSignature
);Features:
- BLS12-381 curve with Ethereum domain separation
- FastAggregateVerify - Single message aggregated over multiple signers
- AggregateVerify - Multiple distinct messages with 1:1 signer mapping
- Platform support: Windows x64, Linux x64, Android
Commits: f2b2d1da, 6eb04d62, c4ba7790
A complete wallet solution for web, mobile, and desktop applications with encrypted vault storage, multi-account support, and comprehensive UI components.
Core wallet services and account management infrastructure.
// Create and unlock vault
var vaultService = new FileWalletVaultService(
storagePath,
new KeyStoreEncryptionStrategy()
);
await vaultService.CreateNewAsync(password);
await vaultService.UnlockAsync(password);
// Create accounts
var accountService = new CoreWalletAccountService();
var mnemonicAccount = await accountService.CreateMnemonicAccountAsync(
mnemonic: "word1 word2 ... word12",
index: 0,
passphrase: null
);
// Add to vault and save
var vault = vaultService.GetCurrentVault();
vault.AddAccount(mnemonicAccount);
await vaultService.SaveAsync();Account Types:
PrivateKeyWalletAccount- Direct private key storageMnemonicWalletAccount- BIP32/BIP39 HD wallet derivationViewOnlyWalletAccount- Read-only address monitoringSmartContractWalletAccount- Contract wallet support
Vault Security:
KeyStoreEncryptionStrategy- Standard Ethereum keystore format (slower but proven)DefaultAes256EncryptionStrategy- Fast AES-256 encryptionBouncyCastleAes256EncryptionStrategy- Alternative provider
Network Management:
var chainService = new ChainManagementService();
// Add from ChainList
await chainService.AddChainFromChainListAsync(chainId);
// Add custom RPC
await chainService.AddRpcEndpointAsync(chainId, rpcUrl);
// Health check
var healthy = await chainService.TestRpcEndpointAsync(rpcUrl);DApp Integration:
IDappPermissionService- Per-origin permission managementNethereumWalletHostProvider-IEthereumHostProviderimplementationNethereumWalletInterceptor- RPC request handling
Commits: 2a68b041, b048fc8c, 37c227fb, 6f07c060
JSON-RPC handler implementation for wallet APIs - MetaMask-compatible RPC support.
// Register all wallet RPC handlers
services.AddWalletRpcHandlers();
// Handlers implement standard Ethereum wallet APIs
public class EthSendTransactionHandler : RpcMethodHandlerBase
{
public override string MethodName => "eth_sendTransaction";
public override async Task<object> HandleAsync(
RpcRequest request,
IWalletContext context)
{
// Parse transaction, show prompt, sign, broadcast
}
}Supported Methods:
| Method | Description |
|---|---|
eth_accounts |
List connected accounts |
eth_requestAccounts |
Request account connection |
eth_chainId |
Current chain ID |
eth_sendTransaction |
Sign and send transaction |
personal_sign |
Sign message |
eth_signTypedData_v4 |
EIP-712 typed data |
wallet_switchEthereumChain |
Switch network |
wallet_addEthereumChain |
Add custom network |
wallet_getPermissions |
Query permissions |
wallet_requestPermissions |
Request permissions |
wallet_revokePermissions |
Revoke access |
Commits: 19ffa941, 62efc517, f10aa4dd
Framework-agnostic ViewModels using CommunityToolkit.Mvvm - shared across Blazor, MAUI, and other UI frameworks.
ViewModels:
AccountListViewModel/CreateAccountViewModel- Account managementWalletDashboardViewModel- Main dashboard with plugin architectureHoldingsViewModel/EditHoldingsViewModel- Token portfolioNetworkSelectorViewModel- Chain selectionContactListViewModel- Address bookDAppTransactionPromptViewModel- Transaction approvalSendNativeTokenViewModel/TokenTransferPluginViewModel- Token transfers
Plugin Architecture:
// Register dashboard plugins
services.AddDashboardPlugin<HoldingsPluginViewModel>("Holdings");
services.AddDashboardPlugin<TransactionsPluginViewModel>("Transactions");
// Plugins implement INavigatablePlugin
public interface INavigatablePlugin
{
string PluginName { get; }
void NavigateTo(string destination);
}Localization:
- Built-in English/Spanish translations
IComponentLocalizer<T>pattern for all components
Commits: 49f60568, 6f07c060, 0308d002, 157e60fa
Production Blazor component library using MudBlazor for responsive, accessible interfaces.
Components:
<!-- Main wallet component -->
<NethereumWallet />
<!-- Account management -->
<AccountList OnAccountSelected="HandleAccountSelected" />
<AccountCard Account="@selectedAccount" />
<CreateAccount OnAccountCreated="HandleCreated" />
<!-- Holdings with tabs -->
<Holdings>
<HoldingsAccountsTab />
<HoldingsNetworksTab />
<HoldingsTokensTab />
</Holdings>
<!-- Dialogs -->
<MessageSigningDialog Message="@message" OnSign="HandleSign" />
<PasswordConfirmationDialog OnConfirm="HandleUnlock" />Features:
- Material Design via MudBlazor 8.x
- Responsive layouts for mobile/desktop
- Real-time balance updates
- Token discovery with progress visualization
- Accessible form controls
Commits: ea15de0c, 75c17c8e, d6648e1e, 8d22c35e
MAUI integration for mobile (iOS/Android) and desktop (Windows/macOS) applications.
// In MauiProgram.cs
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureNethereumWallet(options =>
{
options.StoragePath = FileSystem.AppDataDirectory;
});Target Platforms:
net9.0-android(Android 21+)net9.0-ios(iOS 15+)net9.0-maccatalyst(macOS 12+)net9.0-windows10.0.19041.0(Windows 10+)
Commits: a69a9b05
Comprehensive ERC20 token management with discovery, balances, and pricing.
// Create token service
var tokenService = new Erc20TokenService(
balanceProvider: new MultiCallBalanceProvider(web3),
priceProvider: new CoinGeckoPriceProvider(apiKey),
tokenListProvider: new ResilientTokenListProvider()
);
// Discover tokens for an account
var discovery = await tokenService.DiscoverTokensAsync(
address: "0x...",
chainId: 1,
progress: new Progress<DiscoveryProgress>(p =>
Console.WriteLine($"Checking {p.Current}/{p.Total}"))
);
// Get balances with prices
var balances = await tokenService.GetBalancesWithPricesAsync(
address: "0x...",
chainId: 1,
tokens: discovery.FoundTokens,
currency: "usd"
);
// Refresh from transfer events
var refreshed = await tokenService.RefreshFromEventsAsync(
address: "0x...",
chainId: 1,
fromBlock: lastCheckedBlock
);Multi-Account Support:
var multiService = new MultiAccountTokenService(tokenService);
// Parallel discovery across accounts and chains
var results = await multiService.DiscoverAllAsync(
accounts: new[] { "0xAcc1", "0xAcc2" },
chainIds: new[] { 1, 137, 42161 },
progress: progressReporter
);Providers:
MultiCallBalanceProvider- Efficient batch balance queriesCoinGeckoPriceProvider- Real-time pricingResilientTokenListProvider- Embedded + remote token listsErc20EventScanner- Transfer event monitoring
Commits: 72fcd1aa, 5f8a67db, a233dd23, 244ae8c9
Complete Trezor hardware wallet support across all platforms including mobile.
Full upgrade supporting latest firmware, EIP-712, and multi-OS support.
// Create Trezor manager
var manager = new NethereumTrezorManagerBroker(
deviceFactory,
promptHandler
);
// Get signing session
var session = await manager.GetSessionAsync();
// Sign transaction
var signedTx = await session.SignTransactionAsync(txInput);
// Sign EIP-712 typed data (NEW!)
var signature = await session.SignTypedDataV4Async(typedData);New Features:
- Latest protobuf definitions and firmware support
- EIP-712 typed data signing - Sign structured data on device
- Multi-OS support (Windows, Linux, macOS)
- Improved PIN prompt handler
- Tested with legacy and new Trezor devices
High-level wallet account management for Trezor devices.
// Create Trezor account service
var trezorService = new TrezorWalletAccountService(
sessionProvider,
discoveryService
);
// Discover device and create account
var device = await trezorService.DiscoverDeviceAsync();
var account = await trezorService.CreateAsync(
deviceId: device.Id,
derivationIndex: 0
);
// Add to wallet vault
vault.AddAccount(account);
await vaultService.SaveAsync();Commits: 960db8b9
ViewModels for Trezor UI integration.
TrezorAccountCreationViewModel- Device pairing and account creationTrezorAccountDetailsViewModel- Account properties displayTrezorGroupDetailsViewModel- Hardware device grouping- Comprehensive English/Spanish localization
Commits: d4633613
Blazor components for Trezor hardware wallet UI.
Android USB device driver for MAUI applications - enables Trezor on Android!
// Create USB device factory for Trezor
var usbFactory = new MauiAndroidUsbDeviceFactory(
usbManager,
vendorId: 0x534C, // Trezor
productId: 0x0001
);
// Permission handling
await UsbPermissionHelper.RequestPermissionAsync(device);
// Device implements IDevice from Device.Net
var trezorDevice = await usbFactory.GetDeviceAsync();Features:
MauiAndroidUsbDeviceimplementing Device.NetIDevice- USB enumeration by VendorId/ProductId
- Bulk transfer read/write operations
UsbAttachReceiverfor device attach/detach eventsUsbPermissionHelperfor async permission requests
Commits: a0d2dd0f
Complete Uniswap protocol integration with Permit2 and UniversalRouter support.
// Create Permit2 service
var permit2 = new Permit2Service(web3, permit2Address);
// Sign single token permit
var permitSingle = new PermitSingle
{
Details = new PermitDetails
{
Token = tokenAddress,
Amount = amount,
Expiration = expiration
},
Spender = universalRouterAddress
};
var signedPermit = await permit2.GetSinglePermitWithSignatureAsync(
permitSingle,
signerKey
);
// Sign batch permit
var signedBatch = await permit2.GetBatchPermitWithSignatureAsync(
permitBatch,
signerKey
);UniversalRouter Commands:
// Build swap command sequence
var commands = new List<IUniversalRouterCommand>
{
new Permit2PermitCommand(signedPermit),
new V3SwapExactInCommand(path, recipient, amountIn, minOut),
new PayPortionCommand(token, recipient, bips)
};
await universalRouter.ExecuteAsync(commands, deadline);Components:
Permit2Service- Single and batch permit signingPermitSigner- EIP-712 typed data signature generationUniswapAddresses- Protocol address registry by chain- UniversalRouter command pattern
Commits: 8eb169ec, 5e7262b2, b439a72f
HTTP 402 Payment Required protocol implementation (RFC 8866) - micropayments for APIs.
Server-Side (ASP.NET Core):
// Add X402 middleware
app.UseX402(options =>
{
options.PaymentRoutes = new[]
{
new PaymentRoute
{
Path = "/api/premium/*",
Amount = 1000000, // 1 USDC (6 decimals)
Token = usdcAddress
}
};
options.FacilitatorUrl = "https://facilitator.example.com";
});Client-Side:
var x402Client = new X402HttpClient(
httpClient,
signer,
new X402HttpClientOptions
{
MaxPaymentAmount = 10_000000 // Max 10 USDC
}
);
// Automatic payment handling on 402 response
var response = await x402Client.GetAsync("https://api.example.com/premium/data");Payment Flow:
- Client requests protected resource
- Server returns 402 with payment requirements
- Client signs EIP-3009 authorization
- Facilitator verifies and settles payment
- Server provides resource
Commits: a85cb0ec, 772d3bca, a85b0d8e
Circles protocol integration - decentralized universal basic income on Gnosis Chain.
var hub = new HubService(web3, hubAddress);
// Register as human (requires invitation)
await hub.RegisterHumanRequestAsync(inviterAddress);
// Trust another user
await hub.TrustRequestAsync(trusteeAddress, expiryTime);
// Mint personal tokens (daily UBI)
await hub.PersonalMintRequestAsync();
// Transfer with trust path
await hub.TransferThroughRequestAsync(
from, to, amount, flowEdges
);Contract Services:
HubService- Central protocol coordinatorDemurrageCirclesService- Demurrage token operationsInflationaryCirclesService- Inflationary token operationsNameRegistryService- Avatar name resolution
ChainList Integration (New):
var chainList = new ChainlistRpcApiService();
var chains = await chainList.GetAllChainsAsync();
var rpcs = await chainList.GetRpcsForChainAsync(chainId);CoinGecko Integration (New):
var coingecko = new CoinGeckoApiService(apiKey);
var tokenList = await coingecko.GetTokenListAsync(chainId);
var prices = await coingecko.GetPricesAsync(coinIds, currencies);Etherscan V2 (Major Upgrade):
- Unified API supporting ALL chains
- New account methods: balance at block, multi-balance, beacon withdrawals, ERC-1155/NFT transfers
- New contract methods: creator lookup, proxy verification
- New gas tracker methods
Sourcify V2:
- Updated API endpoints
- Chain info, metadata, and verification responses
Commits: ac1728da, 965ead82, ffc8fc7f
SafeHashesutilities for hash computation- Personal sign support for Safe signatures
- Gnosis Safe V signature conversion
SafeAccountwith contract handler configuration- JSON serialization for Safe web app import/export
Generic Encryption (New):
// Encrypt any data using keystore format
var keyStore = new KeyStoreService();
var encrypted = keyStore.EncryptAndGenerateDefaultKeyStore(
data: mySecretData,
password: password
);
// Decrypt
var decrypted = keyStore.DecryptKeyStore(encrypted, password);- Multiple hash output for signer/wallet matching (Safe compatibility)
- Enhanced
Eip712TypedDataSigner
- Events for Error and Disconnect subscription
- Proper disconnect handling
- Clear selected host provider support
// Change tracking for sync operations
var tracker = new InMemoryChangeTrackerTableRepository();
tracker.EnableTracking = true;
// Get condensed changes for sync
var changes = tracker.GetChanges();
foreach (var change in changes)
{
await syncService.ApplyAsync(change);
}
tracker.ClearChanges();- Merkle Sparse Tree support
Commits: 31e26a61
| Project | Description | Path |
|---|---|---|
| Nethereum.Wallet.Blazor.Demo | Full Blazor wallet demo | src/demos/Nethereum.Wallet.Blazor.Demo |
| Nethereum.Wallet.MauiBlazor.Demo | MAUI mobile wallet demo | src/demos/Nethereum.Wallet.MauiBlazor.Demo |
| Project | Description | Path |
|---|---|---|
| Nethereum.X402.SimpleServer | Basic X402 server | src/demos/Nethereum.X402.SimpleServer |
| Nethereum.X402.SimpleClient | Basic X402 client | src/demos/Nethereum.X402.SimpleClient |
| Nethereum.X402.FacilitatorServer | Payment facilitator | src/demos/Nethereum.X402.FacilitatorServer |
| Project | Description | Path |
|---|---|---|
| Nethereum.Signer.Trezor.Console | Console Trezor integration | consoletests/Nethereum.Signer.Trezor.Console |
| Nethereum.Signer.Trezor.Maui | MAUI Trezor demo with Android USB | consoletests/Nethereum.Signer.Trezor.Maui |
| Project | Description | Path |
|---|---|---|
| MetamaskExampleBlazor.Wasm | EIP-6963 wallet detection | consoletests/MetamaskExampleBlazor.Wasm |
| NethereumReownAppKitBlazor | Reown AppKit integration | consoletests/NethereumReownAppKitBlazor |
- EIP-712 typed data signing support for all external signers
- V4 external signer protocol updates
- Virtual contract message properties for JSON serialization override
IContractServiceConfigurableAccountfor account-based handler configuration- Public
SendAsyncfor direct RPC access wallet_watchAssetobject parameter fix
Commits: 9c85fa9e, bfb1651d, 56f93728, 6f375ac3
ViewOnlyAccountfor simplified impersonationTypedDataRaw.GetChainIdFromDomainextensionChainFeature.FromAddEthereumChainParameterconversion- JSON hex-to-byte array utilities (Newtonsoft & STJ)
- Generic shuffler using
Random.Shared - Electra/Fusaka fork support
Commits: a3e3a0aa, 5c990a57, 2a49e299, 97f7c19c, 60ec1efa
- REST utility updates
MultiPartAsyncsupport
Comprehensive README documentation added to NuGet packages for:
Core: Nethereum.ABI, Nethereum.Util, Nethereum.RLP, Nethereum.Hex, Nethereum.Model, Nethereum.Merkle, Nethereum.Merkle.Patricia
Consensus: Nethereum.Consensus.Ssz, Nethereum.ChainStateVerification
Signing: Nethereum.Signer, Nethereum.Signer.EIP712
Wallet: Nethereum.Wallet, Nethereum.Wallet.RpcRequests, Nethereum.Wallet.UI.Components.Blazor, Nethereum.Wallet.UI.Components.Maui, Nethereum.Wallet.UI.Components.Trezor
Other: Nethereum.EVM, Nethereum.GnosisSafe, Nethereum.BlockchainProcessing, Nethereum.EIP6963WalletInterop, Nethereum.Web3, Nethereum.RPC, Nethereum.Contracts, Nethereum.Mud*
None in this release.
- Juan Blanco (@juanfranblanco)
All packages available on NuGet
Unity releases available on the Unity Releases page.