![]() |
VOOZH | about |
dotnet add package Nethereum.TokenServices --version 6.1.0
NuGet\Install-Package Nethereum.TokenServices -Version 6.1.0
<PackageReference Include="Nethereum.TokenServices" Version="6.1.0" />
<PackageVersion Include="Nethereum.TokenServices" Version="6.1.0" />Directory.Packages.props
<PackageReference Include="Nethereum.TokenServices" />Project file
paket add Nethereum.TokenServices --version 6.1.0
#r "nuget: Nethereum.TokenServices, 6.1.0"
#:package Nethereum.TokenServices@6.1.0
#addin nuget:?package=Nethereum.TokenServices&version=6.1.0Install as a Cake Addin
#tool nuget:?package=Nethereum.TokenServices&version=6.1.0Install as a Cake Tool
A standalone .NET library for ERC20 token discovery, balance retrieval, pricing, and multi-account scanning. Designed for multi-chain support with pluggable providers and discovery strategies.
dotnet add package Nethereum.TokenServices
| Problem | Solution |
|---|---|
| "How do I find all tokens a wallet holds?" | Token discovery via token lists or event scanning |
| "How do I get balances for many tokens efficiently?" | Multicall batching (100+ tokens per call) |
| "How do I get USD prices for tokens?" | CoinGecko integration with caching |
| "How do I track new tokens received?" | Event-based refresh from Transfer logs |
| "How do I scan multiple wallets across chains?" | Multi-account service with parallel scanning |
| "How do I use my own token list/price source?" | Pluggable providers and strategies |
using Nethereum.TokenServices.ERC20;
using Nethereum.TokenServices.ERC20.Balances;
using Nethereum.Web3;
var web3 = new Web3("https://eth.llamarpc.com");
var tokenService = new Erc20TokenService();
// Get all token balances with prices
var balances = await tokenService.GetBalancesWithPricesAsync(
web3,
"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", // Vitalik
chainId: 1,
vsCurrency: "usd",
includeNative: true,
nativeToken: NativeTokenConfig.ForChain(1, "ETH", "Ether"));
foreach (var b in balances.Where(x => x.Value > 0).OrderByDescending(x => x.Value))
{
Console.WriteLine($"{b.Token?.Symbol ?? "ETH"}: {b.BalanceDecimal:N4} @ ${b.Price:N2} = ${b.Value:N2}");
}
Goal: Show all tokens a user holds with current USD values.
var tokenService = new Erc20TokenService();
var web3 = new Web3(rpcUrl);
var balances = await tokenService.GetBalancesWithPricesAsync(
web3, userAddress, chainId, "usd", includeNative: true,
NativeTokenConfig.ForChain(chainId, "ETH", "Ether"));
var portfolio = balances
.Where(b => b.Balance > 0)
.OrderByDescending(b => b.Value)
.ToList();
decimal totalValue = portfolio.Sum(b => b.Value ?? 0);
Goal: Efficiently update balances by only checking tokens that changed.
var tokenService = new Erc20TokenService();
ulong lastScannedBlock = GetLastScannedBlock(); // From your storage
// Scan for Transfer events and get updated balances
// Returns List<TokenBalance> β includes both existing and newly discovered tokens
var updatedBalances = await tokenService.RefreshBalancesFromEventsAsync(
web3, userAddress, chainId,
fromBlock: lastScannedBlock,
existingTokens: currentTokenList,
vsCurrency: "usd");
// Update your local state with refreshed balances
foreach (var balance in updatedBalances)
{
UpdateLocalBalance(balance);
}
Console.WriteLine($"Refreshed {updatedBalances.Count} token balances");
Goal: Scan multiple wallets across multiple chains (e.g., for a portfolio app).
using Nethereum.TokenServices.MultiAccount;
using Nethereum.TokenServices.ERC20.Discovery;
// Get services via DI
var multiAccountService = serviceProvider.GetRequiredService<IMultiAccountTokenService>();
var discoveryStrategy = serviceProvider.GetRequiredService<IDiscoveryStrategy>();
var accounts = new[] { "0xWallet1...", "0xWallet2...", "0xWallet3..." };
var chains = new[] { 1L, 137L, 42161L, 8453L }; // Ethereum, Polygon, Arbitrum, Base
var result = await multiAccountService.ScanAsync(
accounts,
chains,
web3Factory: chainId => new Web3(GetRpcUrl(chainId)),
strategy: discoveryStrategy,
options: new MultiAccountScanOptions
{
MaxParallelChains = 3,
PageSize = 100,
IncludeNativeToken = true
},
progress: new Progress<MultiAccountProgress>(p =>
{
Console.WriteLine($"Progress: {p.OverallPercentComplete:F1}%");
Console.WriteLine($"Chains: {p.CompletedChains}/{p.TotalChains}");
Console.WriteLine($"Tokens found: {p.TokensFound}");
}));
// Access results by chain
foreach (var chainResult in result.ChainResults)
{
Console.WriteLine($"Chain {chainResult.Key}: {chainResult.Value.TokensFound} tokens");
}
// Access results by account
foreach (var accountResult in result.AccountResults)
{
Console.WriteLine($"Account {accountResult.Key}: {accountResult.Value.TokensFound} tokens");
}
Goal: Update prices without re-fetching balances.
var multiAccountService = serviceProvider.GetRequiredService<IMultiAccountTokenService>();
// Prepare token data (account, chain, existing balances)
var accountTokens = new List<(string account, long chainId, IEnumerable<TokenBalance> tokens)>
{
("0xWallet1...", 1, ethereumTokens),
("0xWallet1...", 137, polygonTokens),
("0xWallet2...", 1, wallet2Tokens)
};
var priceResult = await multiAccountService.RefreshPricesAsync(
accountTokens,
currency: "usd");
if (priceResult.Success)
{
Console.WriteLine($"Updated prices for {priceResult.TokensUpdated} tokens");
}
Goal: Track only specific tokens (e.g., USDC, WETH, DAI).
var tokenService = new Erc20TokenService();
var watchlist = new[]
{
new TokenInfo { Address = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", Symbol = "USDC", Decimals = 6 },
new TokenInfo { Address = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", Symbol = "WETH", Decimals = 18 },
new TokenInfo { Address = "0x6B175474E89094C44Da98b954EescdeCB5BAD0", Symbol = "DAI", Decimals = 18 }
};
var balances = await tokenService.GetBalancesForTokensWithPricesAsync(
web3, userAddress, watchlist, "usd");
Discovery strategies determine how tokens are found for an account. Two built-in strategies are provided:
Scans a known list of tokens (from CoinGecko/embedded) and checks balances via multicall.
var strategy = new TokenListDiscoveryStrategy(tokenListProvider, discoveryEngine);
Scans ALL Transfer events for the account from genesis and checks current balances.
var strategy = new EventLogDiscoveryStrategy(eventScanner, balanceProvider, tokenListProvider);
Implement IDiscoveryStrategy for custom sources (e.g., Etherscan API):
public class EtherscanDiscoveryStrategy : IDiscoveryStrategy
{
private readonly string _apiKey;
public string StrategyName => "Etherscan";
public async Task<TokenDiscoveryResult> DiscoverAsync(
IWeb3 web3, string accountAddress, long chainId,
DiscoveryOptions options = null,
IProgress<DiscoveryProgress> progress = null,
CancellationToken ct = default)
{
// Call Etherscan API: /api?module=account&action=tokentx&address={account}
var transfers = await _etherscanClient.GetTokenTransfersAsync(accountAddress);
// Extract unique token addresses
var tokenAddresses = transfers.Select(t => t.ContractAddress).Distinct();
// Get current balances
var tokens = tokenAddresses.Select(a => new TokenInfo { Address = a, Decimals = 18 });
var balances = await _balanceProvider.GetBalancesAsync(web3, accountAddress, tokens);
return TokenDiscoveryResult.Successful(
balances.Where(b => b.Balance > 0).ToList(),
progress, StrategyName);
}
public Task<bool> SupportsChainAsync(long chainId) => Task.FromResult(chainId == 1);
public Task<int> GetExpectedTokenCountAsync(long chainId) => Task.FromResult(0);
}
// Register in DI
services.AddErc20TokenServices()
.UseDiscoveryStrategy<EtherscanDiscoveryStrategy>();
public class MyTokenListProvider : ITokenListProvider
{
public async Task<List<TokenInfo>> GetTokensAsync(long chainId)
{
// Fetch from your database, API, or static list
return await _myDatabase.GetTokensForChain(chainId);
}
public Task<TokenInfo> GetTokenAsync(long chainId, string address) { ... }
public Task<bool> SupportsChainAsync(long chainId) { ... }
}
// Use it
var tokenService = new Erc20TokenService(tokenListProvider: new MyTokenListProvider());
// Or via DI
services.AddErc20TokenServices().UseTokenListProvider<MyTokenListProvider>();
public class MyPriceProvider : ITokenPriceProvider
{
public async Task<Dictionary<string, TokenPrice>> GetPricesByContractAsync(
long chainId, IEnumerable<string> addresses, string currency)
{
// Fetch from your price source
return await _myPriceApi.GetPrices(chainId, addresses, currency);
}
// ... other interface methods
}
services.AddErc20TokenServices().UsePriceProvider<MyPriceProvider>();
// Use file-based cache
services.AddErc20TokenServices(options =>
{
options.UseFileCache = true;
options.CacheDirectory = "/data/token-cache";
});
// Or provide custom cache (Redis, etc.)
public class RedisCacheProvider : ICacheProvider { ... }
services.AddErc20TokenServices().UseCacheProvider<RedisCacheProvider>();
The library uses pluggable storage interfaces for persisting token list diffs and coin mappings. Default implementations are file-based, but you can easily swap to PostgreSQL, SQLite, or any database:
// Default: file-based storage
services.AddErc20TokenServices(options =>
{
options.UseFileDiffStorage = true;
options.TokenListDiffStorageDirectory = "/data/tokenlists";
options.CoinMappingDiffStorageDirectory = "/data/coinmappings";
});
// PostgreSQL implementation
public class PostgresTokenListDiffStorage : ITokenListDiffStorage
{
private readonly NpgsqlConnection _connection;
public async Task<List<TokenInfo>> GetAdditionalTokensAsync(long chainId)
{
return await _connection.QueryAsync<TokenInfo>(
"SELECT * FROM additional_tokens WHERE chain_id = @chainId",
new { chainId });
}
public async Task SaveAdditionalTokensAsync(long chainId, List<TokenInfo> tokens)
{
await _connection.ExecuteAsync(
"INSERT INTO additional_tokens (chain_id, address, symbol, decimals) VALUES ...",
tokens.Select(t => new { chainId, t.Address, t.Symbol, t.Decimals }));
}
public async Task<DateTime?> GetLastUpdateAsync(long chainId)
{
return await _connection.QuerySingleOrDefaultAsync<DateTime?>(
"SELECT last_update FROM token_list_metadata WHERE chain_id = @chainId",
new { chainId });
}
public async Task SetLastUpdateAsync(long chainId, DateTime updateTime)
{
await _connection.ExecuteAsync(
"INSERT INTO token_list_metadata (chain_id, last_update) VALUES (@chainId, @updateTime) " +
"ON CONFLICT (chain_id) DO UPDATE SET last_update = @updateTime",
new { chainId, updateTime });
}
public async Task ClearAsync(long chainId)
{
await _connection.ExecuteAsync(
"DELETE FROM additional_tokens WHERE chain_id = @chainId;" +
"DELETE FROM token_list_metadata WHERE chain_id = @chainId",
new { chainId });
}
}
// Register your custom storage
services.AddErc20TokenServices()
.UseTokenListDiffStorage<PostgresTokenListDiffStorage>()
.UseCoinMappingDiffStorage<PostgresCoinMappingDiffStorage>();
Storage Interfaces:
| Interface | Purpose | Default |
|---|---|---|
ITokenListDiffStorage |
Stores tokens discovered beyond embedded lists | FileTokenListDiffStorage |
ICoinMappingDiffStorage |
Stores contractβCoinGecko ID mappings | FileCoinMappingDiffStorage |
ICacheProvider |
General key-value cache with expiry | MemoryCacheProvider |
services.AddErc20TokenServices();
services.AddErc20TokenServices(options =>
{
options.UseFileCache = true;
options.CacheDirectory = "/data/cache";
options.DefaultCurrency = "usd";
options.PriceCacheExpiry = TimeSpan.FromMinutes(5);
options.TokenListCacheExpiry = TimeSpan.FromDays(7);
options.MultiCallBatchSize = 100;
options.MaxParallelChains = 3;
});
services.AddErc20TokenServices()
.UseTokenListProvider<MyTokenListProvider>()
.UsePriceProvider<MyPriceProvider>()
.UseDiscoveryStrategy<MyDiscoveryStrategy>()
.UseCacheProvider<RedisCacheProvider>();
After calling AddErc20TokenServices(), these services are available:
| Interface | Default Implementation | Lifetime |
|---|---|---|
IErc20TokenService |
Erc20TokenService |
Singleton |
ITokenListProvider |
ResilientTokenListProvider |
Singleton |
ITokenBalanceProvider |
MultiCallBalanceProvider |
Singleton |
ITokenPriceProvider |
CoinGeckoPriceProvider |
Singleton |
ITokenEventScanner |
Erc20EventScanner |
Singleton |
ITokenDiscoveryEngine |
TokenDiscoveryEngine |
Singleton |
IDiscoveryStrategy |
TokenListDiscoveryStrategy |
Singleton |
IMultiAccountTokenService |
MultiAccountTokenService |
Singleton |
ICacheProvider |
MemoryCacheProvider |
Singleton |
ITokenListDiffStorage |
NullTokenListDiffStorage* |
Singleton |
ICoinMappingDiffStorage |
NullCoinMappingDiffStorage* |
Singleton |
*Use UseFileDiffStorage = true option or UseTokenListDiffStorage<T>() builder method for persistence.
The Token Catalog provides a persistent, refreshable token registry that replaces the legacy diff-based storage. It acts as a local database of known tokens per chain, with automatic seeding from embedded lists and refresh from external sources like CoinGecko.
using Nethereum.TokenServices.Catalog;
// Basic setup with default file-based repository
services.AddTokenCatalog(options =>
{
options.CatalogDirectory = "/data/token-catalog";
options.AutoSeedFromEmbedded = true;
options.DefaultRefreshInterval = TimeSpan.FromHours(6);
options.RegisterCoinGeckoSource = true;
});
// With custom repository (e.g., database-backed)
services.AddTokenCatalogWithCustomRepository<MyDatabaseCatalogRepository>();
var repository = serviceProvider.GetRequiredService<ITokenCatalogRepository>();
// Get all tokens for a chain
var tokens = await repository.GetAllTokensAsync(chainId: 1);
Console.WriteLine($"Known tokens on Ethereum: {tokens.Count}");
// Look up a specific token
var usdc = await repository.GetTokenByAddressAsync(chainId: 1, "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48");
Console.WriteLine($"{usdc.Symbol}: {usdc.Name} ({usdc.Decimals} decimals)");
// Get tokens added since a date
var recentTokens = await repository.GetTokensAddedSinceAsync(chainId: 1, DateTime.UtcNow.AddDays(-7));
var refreshService = serviceProvider.GetRequiredService<ITokenCatalogRefreshService>();
// Check if refresh is needed (based on min interval)
if (await refreshService.ShouldRefreshAsync(chainId: 1))
{
var result = await refreshService.RefreshAsync(chainId: 1, new CatalogRefreshOptions
{
ForceRefresh = false,
IncrementalOnly = true,
UpdateExistingTokens = false
});
Console.WriteLine($"Source: {result.SourceUsed}");
Console.WriteLine($"Added: {result.TotalTokensAdded}, Updated: {result.TotalTokensUpdated}");
Console.WriteLine($"Total in catalog: {result.TotalTokensInCatalog}");
}
Bridge the catalog into the ITokenListProvider interface used by Erc20TokenService:
var catalogProvider = new CatalogTokenListProviderAdapter(repository, autoSeed: true);
var tokenService = new Erc20TokenService(tokenListProvider: catalogProvider);
Implement ITokenCatalogRefreshSource to add your own token data sources:
public class MyCustomTokenSource : ITokenCatalogRefreshSource
{
public string SourceName => "MyCustomSource";
public int Priority => 10; // Lower = tried first
public Task<bool> SupportsChainAsync(long chainId, CancellationToken ct) =>
Task.FromResult(chainId == 1);
public async Task<TokenCatalogRefreshResult> FetchTokensAsync(
long chainId, DateTime? sinceUtc, CancellationToken ct)
{
var tokens = await FetchFromMyApi(chainId, sinceUtc);
return new TokenCatalogRefreshResult
{
Success = true,
Tokens = tokens.Select(t => new CatalogTokenInfo
{
Address = t.Address,
Symbol = t.Symbol,
Name = t.Name,
Decimals = t.Decimals,
ChainId = chainId,
Source = SourceName
}).ToList()
};
}
public Task<RateLimitInfo> GetRateLimitInfoAsync(CancellationToken ct) =>
Task.FromResult(new RateLimitInfo { IsRateLimited = false });
}
// Register
services.AddTokenCatalog().AddRefreshSource<MyCustomTokenSource>();
var migrationService = new TokenCatalogMigrationService(catalogRepository, legacyDiffStorage);
// Migrate a single chain
var result = await migrationService.MigrateAsync(chainId: 1, new MigrationOptions
{
ForceMigration = false,
ClearLegacyAfterMigration = true
});
Console.WriteLine($"Migrated {result.MigratedTokenCount} tokens ({result.EmbeddedTokenCount} embedded + {result.DiffTokenCount} custom)");
// Migrate all chains
var allResults = await migrationService.MigrateAllChainsAsync();
public class CatalogTokenInfo
{
public string Address { get; set; }
public string Symbol { get; set; }
public string Name { get; set; }
public int Decimals { get; set; }
public string LogoUri { get; set; }
public long ChainId { get; set; }
public string CoinGeckoId { get; set; }
public DateTime AddedAtUtc { get; set; }
public DateTime? UpdatedAtUtc { get; set; }
public string Source { get; set; }
// Convert to/from TokenInfo
public static CatalogTokenInfo FromTokenInfo(TokenInfo tokenInfo, string source = "embedded");
public TokenInfo ToTokenInfo();
}
Nethereum.TokenServices/
βββ ERC20/
β βββ IErc20TokenService.cs # Main facade
β βββ Erc20TokenService.cs
β βββ Discovery/
β β βββ IDiscoveryStrategy.cs # Plugin interface
β β βββ TokenListDiscoveryStrategy.cs
β β βββ EventLogDiscoveryStrategy.cs
β β βββ ITokenListProvider.cs
β β βββ ITokenListDiffStorage.cs # Pluggable storage
β β βββ ResilientTokenListProvider.cs
β β βββ EmbeddedTokenListProvider.cs
β β βββ CoinGeckoTokenListProvider.cs
β βββ Balances/
β β βββ ITokenBalanceProvider.cs
β β βββ MultiCallBalanceProvider.cs
β βββ Pricing/
β β βββ ITokenPriceProvider.cs
β β βββ ICoinMappingDiffStorage.cs # Pluggable storage
β β βββ CoinGeckoPriceProvider.cs
β β βββ BatchPriceService.cs
β βββ Events/
β β βββ ITokenEventScanner.cs
β β βββ Erc20EventScanner.cs
β βββ Models/
β βββ TokenInfo.cs
β βββ TokenBalance.cs
β βββ TokenPrice.cs
βββ MultiAccount/
β βββ IMultiAccountTokenService.cs # Multi-wallet scanning
β βββ MultiAccountTokenService.cs
β βββ Models/
βββ Catalog/
β βββ ITokenCatalogRepository.cs # Persistent catalog storage
β βββ ITokenCatalogRefreshService.cs # Refresh orchestration
β βββ ITokenCatalogRefreshSource.cs # Plugin interface for sources
β βββ TokenCatalogRefreshService.cs
β βββ CatalogTokenInfo.cs # Catalog token model
β βββ CatalogTokenListProviderAdapter.cs # Bridge to ITokenListProvider
β βββ TokenCatalogMigrationService.cs # Legacy diff β catalog migration
β βββ TokenCatalogServiceCollectionExtensions.cs # DI setup
βββ Caching/
β βββ ICacheProvider.cs
β βββ MemoryCacheProvider.cs
β βββ FileCacheProvider.cs
β βββ FileStorageBase.cs # Base class for file storage
β βββ FileTokenListDiffStorage.cs # File-based impl
β βββ FileCoinMappingDiffStorage.cs # File-based impl
β βββ NullTokenListDiffStorage.cs # No-op impl
β βββ NullCoinMappingDiffStorage.cs # No-op impl
βββ Resources/ # Embedded token lists
| Chain | Chain ID | Native Token |
|---|---|---|
| Ethereum | 1 | ETH |
| Optimism | 10 | ETH |
| BNB Chain | 56 | BNB |
| Gnosis | 100 | xDAI |
| Polygon | 137 | MATIC |
| zkSync Era | 324 | ETH |
| Base | 8453 | ETH |
| Arbitrum One | 42161 | ETH |
| Celo | 42220 | CELO |
| Avalanche | 43114 | AVAX |
| Linea | 59144 | ETH |
| Data | Default Expiry |
|---|---|
| Token Lists | 7 days |
| Prices | 5 minutes |
| Coin Mappings | 7 days |
| Platforms | 30 days |
InitializeCacheAsync at startup to preload token listsBatchPriceService for many tokensNethereum.Web3Nethereum.DataServices (CoinGecko API)Nethereum.BlockchainProcessing (Event scanning)Microsoft.Extensions.DependencyInjection.AbstractionsMIT License - see the main Nethereum repository for details.
| 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 was computed. 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 is compatible. net463 net463 was computed. net47 net47 was computed. net471 net471 was computed. net472 net472 was computed. 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 1 NuGet packages that depend on Nethereum.TokenServices:
| Package | Downloads |
|---|---|
|
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.