diff --git a/src/Net.Cache.DynamoDb.ERC20/Erc20CacheService.cs b/src/Net.Cache.DynamoDb.ERC20/Erc20CacheService.cs index bf38efe..e52b17a 100644 --- a/src/Net.Cache.DynamoDb.ERC20/Erc20CacheService.cs +++ b/src/Net.Cache.DynamoDb.ERC20/Erc20CacheService.cs @@ -1,4 +1,5 @@ using System; +using Nethereum.Web3; using System.Threading.Tasks; using Net.Web3.EthereumWallet; using Net.Cache.DynamoDb.ERC20.Rpc; @@ -39,11 +40,27 @@ public Erc20CacheService() ) { } - /// - public async Task GetOrAddAsync(HashKey hashKey, Func> rpcUrlFactory, Func> multiCallFactory) + /// + public Task GetOrAddAsync(HashKey hashKey, Func> rpcUrlFactory, Func> multiCallFactory) { - if (hashKey == null) throw new ArgumentNullException(nameof(hashKey)); if (rpcUrlFactory == null) throw new ArgumentNullException(nameof(rpcUrlFactory)); + + return GetOrAddAsync( + hashKey, + async () => + { + var rpcUrl = await rpcUrlFactory().ConfigureAwait(false); + return new Nethereum.Web3.Web3(rpcUrl); + }, + multiCallFactory + ); + } + + /// + public async Task GetOrAddAsync(HashKey hashKey, Func> web3Factory, Func> multiCallFactory) + { + if (hashKey == null) throw new ArgumentNullException(nameof(hashKey)); + if (web3Factory == null) throw new ArgumentNullException(nameof(web3Factory)); if (multiCallFactory == null) throw new ArgumentNullException(nameof(multiCallFactory)); if (_inMemoryCache.TryGetValue(hashKey.Value, out var cachedEntry)) return cachedEntry; @@ -57,15 +74,15 @@ public async Task GetOrAddAsync(HashKey hashKey, FuncFactory used to resolve the address of the multicall contract. /// The cached or newly created instance. public Task GetOrAddAsync(HashKey hashKey, Func> rpcUrlFactory, Func> multiCallFactory); + + /// + /// Retrieves a cached ERC20 token entry or adds a new one when it is missing using a Web3 factory. + /// + /// The composite key of chain identifier and token address. + /// Factory used to resolve the Web3 client instance. + /// Factory used to resolve the address of the multicall contract. + /// The cached or newly created instance. + public Task GetOrAddAsync(HashKey hashKey, Func> web3Factory, Func> multiCallFactory); } } diff --git a/src/Net.Cache.DynamoDb.ERC20/README.md b/src/Net.Cache.DynamoDb.ERC20/README.md index 2f50ea0..ac41dd9 100644 --- a/src/Net.Cache.DynamoDb.ERC20/README.md +++ b/src/Net.Cache.DynamoDb.ERC20/README.md @@ -42,7 +42,9 @@ var cacheService = new Erc20CacheService(dynamoDbClient, erc20ServiceFactory); #### Caching ERC20 Token Information -To cache ERC20 token information, create a `HashKey` and use the `GetOrAddAsync` method of `Erc20CacheService`: +To cache ERC20 token information, create a `HashKey` and use one of the `GetOrAddAsync` overloads of `Erc20CacheService`. + +The overload that accepts RPC and multicall address factories is useful when you only need to supply connection metadata: ```csharp var chainId = 1L; // Ethereum mainnet @@ -58,4 +60,16 @@ var tokenInfo = await cacheService.GetOrAddAsync( Console.WriteLine($"Token Name: {tokenInfo.Name}, Symbol: {tokenInfo.Symbol}"); ``` -This method retrieves the token information from the cache if it exists, or fetches it from the blockchain and stores it in both the DynamoDB table and the in-memory cache otherwise. \ No newline at end of file +If you need to control the entire `IWeb3` client creation, you can use the overload that accepts a `Func>` alongside the multicall factory: + +```csharp +var tokenInfo = await cacheService.GetOrAddAsync( + hashKey, + web3Factory: () => Task.FromResult((IWeb3)new Web3("https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID")), + multiCallFactory: () => Task.FromResult(new EthereumAddress("0x...multicall")) +); + +Console.WriteLine($"Token Name: {tokenInfo.Name}, Symbol: {tokenInfo.Symbol}"); +``` + +Both overloads retrieve the token information from the cache if it exists, or fetch it from the blockchain and store it in both the DynamoDB table and the in-memory cache otherwise. \ No newline at end of file