Nethereum is the primary .NET library for talking to the Avalanche C-Chain. Because the C-Chain runs a standard EVM (chain ID 43114), every Nethereum call works against https://avalanche.therpc.io/YOUR_API_KEY exactly as it would against any Ethereum-compatible node, with AVAX as the gas token. Nethereum targets .NET Standard 2.0+, so the same code runs across Unity3D games, Xamarin mobile apps, ASP.NET Core services, and Blazor front ends. Add it to your project with dotnet add package Nethereum.Web3.
Nethereum builds on .NET Standard 2.0+, which keeps it compatible across Unity3D, Xamarin, ASP.NET Core, and Blazor — one Avalanche C-Chain integration for desktop, server, mobile, and game runtimes. Pull it in from NuGet with dotnet add package Nethereum.Web3.
Nethereum
Create a client with new Web3("https://avalanche.therpc.io/YOUR_API_KEY") and you are connected to the C-Chain. Every IO operation in Nethereum returns an async Task, so always await it. Blocking with .Result or .Wait() can deadlock under ASP.NET's synchronization context — keep the call chain async all the way up. With Avalanche's roughly 1–2 second finality, awaited balance and receipt calls return quickly.
using Nethereum.Web3;
using Nethereum.Web3.Accounts;
using Nethereum.Util;
using Nethereum.Hex.HexTypes;
public class EthereumService
{
private readonly Web3 _web3;
public EthereumService(string url)
{
_web3= new Web3(url);
}
public async Task<decimal> GetBalanceAsync(string address)
{
var balance = await _web3.Eth.GetBalance.SendRequestAsync(address);
return Web3.Convert.FromWei(balance.Value);
}
public async Task<string> SendTransactionAsync(
string privateKey,
string toAddress,
decimal etherAmount)
{
var account = new Account(privateKey);
var web3= new Web3(account, _web3.Client.Url);
var transaction = await web3.Eth.GetEtherTransferService()
Key features: full Avalanche C-Chain integration over JSON-RPC, smart contract deployment and interaction, HD wallet support, Unity3D and Xamarin runtimes, and IPC/RPC/WebSocket transports
Smart Contract Integration
To work with a deployed C-Chain contract — say a Trader Joe pair or an Aave pool — get a handle with _web3.Eth.GetContract(abi, contractAddress). From there, GetFunction(name) gives you a callable; use CallAsync<T> for read-only view calls (no AVAX gas spent) and SendTransactionAsync for state-changing writes that submit a signed transaction.
public class SmartContractService
{
private readonly Web3 _web3;
private readonly Contract _contract;
public SmartContractService(string url, string contractAddress, string abi)
In an ASP.NET Core app, register EthereumService once in the DI container (in Program.cs or Startup.ConfigureServices) and let the framework inject it into your controllers — a single shared C-Chain client across requests. Inside each action, wrap the awaited calls in try/catch so an RPC timeout or a reverted transaction surfaces as a clean BadRequest instead of an unhandled 500.
public EthereumController(EthereumService ethereumService)
{
_ethereumService = ethereumService;
}
[HttpGet("balance/{address}")]
public async Task<ActionResult<decimal>> GetBalance(string address)
{
try
{
var balance = await _ethereumService.GetBalanceAsync(address);
return Ok(balance);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
}
Event Handling
To watch contract events on the C-Chain — a Transfer on an ERC-20, a Swap on a GMX or Trader Joe pool — define an event DTO and call GetEvent<TEventDTO>(contractAddress). Build a filter with CreateFilterInput() and poll it with GetFilterChanges. Given Avalanche's fast block cadence, a short poll interval keeps your handler close to real time without a WebSocket subscription.
public class EventMonitorService
{
private readonly Web3 _web3;
public async Task MonitorEventsAsync(string contractAddress, string eventName)
{
var filterAll = _web3.Eth.GetEvent<YourEventDTO>(contractAddress)
.CreateFilterInput();
var subscription = _web3.Eth.GetEvent<YourEventDTO>(contractAddress)
.GetFilterChanges(filterAll);
subscription.Subscribe(evt =>
{
Console.WriteLine($"New event: {evt.Event}");
});
}
}
Unity3D Integration
For a Unity3D game that reads AVAX balances or NFT ownership on the C-Chain, initialize Web3 once in Awake() or Start() pointing at https://avalanche.therpc.io/YOUR_API_KEY. Be careful with async void in MonoBehaviour: it cannot be awaited and swallows exceptions, so reserve it for top-level lifecycle hooks like Start() and route the real work through Task-returning helpers. Wrap those in try/catch and log failures through Debug.LogError so a network blip never crashes the play session.
public class EthereumUnityManager : MonoBehaviour
{
private Web3 _web3;
private async void Start()
{
_web3= new Web3("https://avalanche.therpc.io/YOUR_API_KEY");
await InitializeWalletAsync();
}
private async Task InitializeWalletAsync()
{
try
{
var balance = await _web3.Eth.GetBalance.SendRequestAsync("YOUR_ADDRESS");