Gnosis

Gnosis

C#

Nethereum is the primary .NET library for talking to Gnosis Chain, the Proof-of-Stake EVM L1 secured by the Gnosis Beacon Chain (chain ID 100). It targets .NET Standard 2.0+, so the same code runs across Unity3D, Xamarin, ASP.NET Core, and Blazor. Because Gnosis is fully EVM-compatible and uses the xDAI stablecoin for gas, every standard Nethereum call works unchanged — only the endpoint differs. Install it from NuGet with dotnet add package Nethereum.Web3 and point the client at https://gnosis.therpc.io/YOUR_API_KEY.

Nethereum targets .NET Standard 2.0+, which keeps it compatible with Unity3D games, Xamarin mobile apps, ASP.NET Core services, and Blazor front-ends that connect to Gnosis Chain. Pull it into any project with the NuGet command dotnet add package Nethereum.Web3.

Nethereum

Create a client with new Web3("https://gnosis.therpc.io/YOUR_API_KEY") and you are connected to Gnosis Chain. Every method that touches the network — balance reads, transaction sends, contract calls — returns an async Task, so always await it. Never block on .Result or .Wait(): in ASP.NET and Unity contexts that pattern can deadlock the synchronization context. With ~5 second Gnosis block times, awaiting also keeps your UI responsive while a transaction confirms.

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()
.TransferEtherAsync(toAddress, etherAmount);
return transaction;
}
}

Smart Contract Integration

To work with a deployed contract — a Safe wallet, an ERC-20, or a Circles token on Gnosis Chain — get a handle from _web3.Eth.GetContract(abi, contractAddress). For read-only views, fetch the function with GetFunction(name) and call CallAsync<T>(), which costs no xDAI. For state-changing methods, use SendTransactionAsync(), which submits a transaction that the network charges in xDAI gas.

public class SmartContractService
{
private readonly Web3 _web3;
private readonly Contract _contract;
public SmartContractService(string url, string contractAddress, string abi)
{
_web3 = new Web3(url);
_contract = _web3.Eth.GetContract(abi, contractAddress);
}
public async Task<T> CallFunctionAsync<T>(string functionName, params object[] parameters)
{
var function = _contract.GetFunction(functionName);
return await function.CallAsync<T>(parameters);
}
public async Task<string> ExecuteFunctionAsync(
string functionName,
string fromAddress,
params object[] parameters)
{
var function = _contract.GetFunction(functionName);
return await function.SendTransactionAsync(fromAddress, parameters);
}
}

ASP.NET Integration

In an ASP.NET Core service that fronts Gnosis Chain, register EthereumService in the DI container in Program.cs (or Startup.cs) and let the framework resolve it into your controllers — that keeps a single configured Gnosis client per request scope. Wrap each await in a try/catch so a failed RPC call or a reverted xDAI transaction returns BadRequest with the error message instead of bubbling up as a 500.

[ApiController]
[Route("api/[controller]")]
public class EthereumController : ControllerBase
{
private readonly EthereumService _ethereumService;
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 activity on Gnosis Chain — token Transfer logs, Gnosis Pay settlements, or prediction-market events — define an event DTO and call _web3.Eth.GetEvent<YourEventDTO>(contractAddress). Build a filter with CreateFilterInput() and poll it with GetFilterChanges. With Gnosis blocks landing roughly every 5 seconds, a short polling interval keeps your listener close to the chain head.

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

In a Unity3D game that settles in xDAI on Gnosis Chain, initialize the Web3 client once in Start() or Awake() with https://gnosis.therpc.io/YOUR_API_KEY. Be careful with async void in MonoBehaviour: it is only appropriate for top-level entry points like Start() because exceptions inside it cannot be caught by the caller. Push the real work into Task-returning helpers (as InitializeWalletAsync below) and await them, so balance reads and transaction sends report errors cleanly through Debug.LogError.

public class EthereumUnityManager : MonoBehaviour
{
private Web3 _web3;
private async void Start()
{
_web3 = new Web3("https://gnosis.therpc.io/YOUR_API_KEY");
await InitializeWalletAsync();
}
private async Task InitializeWalletAsync()
{
try
{
var balance = await _web3.Eth.GetBalance.SendRequestAsync("YOUR_ADDRESS");
Debug.Log($"Wallet Balance: {Web3.Convert.FromWei(balance.Value)} xDAI");
}
catch (Exception ex)
{
Debug.LogError($"Failed to initialize wallet: {ex.Message}");
}
}
}

Ready to call this in production?

Free tier covers personal projects. Pay-as-you-go scales without a card.