Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<PackageReference Include="FluentValidation" Version="11.11.0" />
<PackageReference Include="Net.Cryptography.SHA256" Version="1.1.0" />
<PackageReference Include="Net.Web3.EthereumWallet" Version="1.2.2" />
<PackageReference Include="Nethereum.Contracts" Version="5.0.0" />
<PackageReference Include="Nethereum.Web3" Version="5.0.0" />
</ItemGroup>

Expand Down
34 changes: 18 additions & 16 deletions src/Net.Cache.DynamoDb.ERC20/RPC/ERC20Service.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using Net.Cache.DynamoDb.ERC20.Rpc.Extensions;
using Net.Cache.DynamoDb.ERC20.Rpc.Models;
using Net.Cache.DynamoDb.ERC20.Rpc.Validators;
using Nethereum.Contracts.QueryHandlers.MultiCall;
using Nethereum.Contracts.Standards.ERC20.ContractDefinition;

namespace Net.Cache.DynamoDb.ERC20.Rpc
Expand Down Expand Up @@ -37,34 +38,35 @@ public async Task<Erc20TokenData> GetErc20TokenAsync(EthereumAddress token)
{
if (token == null) throw new ArgumentNullException(nameof(token));

var multiCallFunction = new MultiCallFunction(
calls: new[]
var multiCallFunction = new Aggregate3Function
{
Calls = new List<Call3>
{
new MultiCall(to: token, data: new NameFunction().GetCallData()),
new MultiCall(to: token, data: new SymbolFunction().GetCallData()),
new MultiCall(to: token, data: new DecimalsFunction().GetCallData()),
new MultiCall(to: token, data: new TotalSupplyFunction().GetCallData())
new Call3 { Target = token, CallData = new NameFunction().GetCallData() },
new Call3 { Target = token, CallData = new SymbolFunction().GetCallData() },
new Call3 { Target = token, CallData = new DecimalsFunction().GetCallData() },
new Call3 { Target = token, CallData = new TotalSupplyFunction().GetCallData() }
}
);

var handler = _web3.Eth.GetContractQueryHandler<MultiCallFunction>();
};
var handler = _web3.Eth.GetContractQueryHandler<Aggregate3Function>();
var response = await handler
.QueryAsync<List<byte[]>>(_multiCall, multiCallFunction)
.QueryAsync<Aggregate3OutputDTO>(_multiCall, multiCallFunction)
.ConfigureAwait(false);
var responseValidator = new MultiCallResponseValidator(multiCallFunction.Calls.Length);
var responseValidator = new MultiCallResponseValidator(multiCallFunction.Calls.Count);
var validation = await responseValidator
.ValidateAsync(response)
.ValidateAsync(response.ReturnData.Select(x => x.ReturnData).ToArray())
.ConfigureAwait(false);
if (!validation.IsValid)
{
var error = string.Join(" ", validation.Errors.Select(e => e.ErrorMessage));
throw new Erc20QueryException(token, error);
}

var name = response[0].Decode<NameOutputDTO>().Name;
var symbol = response[1].Decode<SymbolOutputDTO>().Symbol;
var decimals = response[2].Decode<DecimalsOutputDTO>().Decimals;
var supply = response[3].Decode<TotalSupplyOutputDTO>().TotalSupply;
var name = response.ReturnData[0].ReturnData.Decode<NameOutputDTO>().Name;
var symbol = response.ReturnData[1].ReturnData.Decode<SymbolOutputDTO>().Symbol;
var decimals = response.ReturnData[2].ReturnData.Decode<DecimalsOutputDTO>().Decimals;
var supply = response.ReturnData[3].ReturnData.Decode<TotalSupplyOutputDTO>().TotalSupply;

var tokenResult = new Erc20TokenData(token, name, symbol, decimals, supply);
var tokenValidator = new Erc20TokenValidator();
Expand Down
34 changes: 0 additions & 34 deletions src/Net.Cache.DynamoDb.ERC20/RPC/Models/MultiCall.cs

This file was deleted.

34 changes: 0 additions & 34 deletions src/Net.Cache.DynamoDb.ERC20/RPC/Models/MultiCallFunction.cs

This file was deleted.

34 changes: 18 additions & 16 deletions tests/Net.Cache.DynamoDb.ERC20.Tests/Rpc/Erc20ServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
using Net.Web3.EthereumWallet;
using Nethereum.Contracts.Services;
using Net.Cache.DynamoDb.ERC20.Rpc;
using Net.Cache.DynamoDb.ERC20.Rpc.Models;
using Nethereum.Contracts.ContractHandlers;
using Net.Cache.DynamoDb.ERC20.Rpc.Exceptions;
using Nethereum.Contracts.QueryHandlers.MultiCall;

namespace Net.Cache.DynamoDb.ERC20.Tests.Rpc;

Expand Down Expand Up @@ -39,7 +39,7 @@ public class GetErc20TokenAsync
[Fact]
public async Task WhenTokenNull_ShouldThrow()
{
var handler = new Mock<IContractQueryHandler<MultiCallFunction>>();
var handler = new Mock<IContractQueryHandler<Aggregate3Function>>();
var service = CreateService(handler.Object);
var act = async () => await service.GetErc20TokenAsync(null!);
await act.Should().ThrowAsync<ArgumentNullException>();
Expand All @@ -49,9 +49,9 @@ public async Task WhenTokenNull_ShouldThrow()
public async Task WhenResponseValid_ShouldReturnToken()
{
var response = BuildResponse("Token", "TKN", 18, new BigInteger(1000));
var handlerMock = new Mock<IContractQueryHandler<MultiCallFunction>>();
var handlerMock = new Mock<IContractQueryHandler<Aggregate3Function>>();
handlerMock
.Setup(h => h.QueryAsync<List<byte[]>>(It.IsAny<string>(), It.IsAny<MultiCallFunction>(), It.IsAny<BlockParameter>()))
.Setup(h => h.QueryAsync<Aggregate3OutputDTO>(It.IsAny<string>(), It.IsAny<Aggregate3Function>(), It.IsAny<BlockParameter>()))
.ReturnsAsync(response);
var service = CreateService(handlerMock.Object);

Expand All @@ -68,9 +68,9 @@ public async Task WhenResponseValid_ShouldReturnToken()
public async Task WhenTokenInvalid_ShouldThrow()
{
var response = BuildResponse(string.Empty, "TKN", 18, new BigInteger(1000));
var handlerMock = new Mock<IContractQueryHandler<MultiCallFunction>>();
var handlerMock = new Mock<IContractQueryHandler<Aggregate3Function>>();
handlerMock
.Setup(h => h.QueryAsync<List<byte[]>>(It.IsAny<string>(), It.IsAny<MultiCallFunction>(), It.IsAny<BlockParameter>()))
.Setup(h => h.QueryAsync<Aggregate3OutputDTO>(It.IsAny<string>(), It.IsAny<Aggregate3Function>(), It.IsAny<BlockParameter>()))
.ReturnsAsync(response);
var service = CreateService(handlerMock.Object);

Expand All @@ -81,24 +81,26 @@ await act.Should().ThrowAsync<Erc20QueryException>()
}
}

private static Erc20Service CreateService(IContractQueryHandler<MultiCallFunction> handler)
private static Erc20Service CreateService(IContractQueryHandler<Aggregate3Function> handler)
{
var web3Mock = new Mock<IWeb3>();
var ethMock = new Mock<IEthApiContractService>();
ethMock.Setup(e => e.GetContractQueryHandler<MultiCallFunction>()).Returns(handler);
ethMock.Setup(e => e.GetContractQueryHandler<Aggregate3Function>()).Returns(handler);
web3Mock.SetupGet(w => w.Eth).Returns(ethMock.Object);
return new Erc20Service(web3Mock.Object, EthereumAddress.ZeroAddress);
}

private static List<byte[]> BuildResponse(string name, string symbol, byte decimals, BigInteger supply)
private static Aggregate3OutputDTO BuildResponse(string name, string symbol, byte decimals, BigInteger supply)
{
var abiEncode = new ABIEncode();
return
[
abiEncode.GetABIEncoded(new ABIValue("string", name)),
abiEncode.GetABIEncoded(new ABIValue("string", symbol)),
abiEncode.GetABIEncoded(new ABIValue("uint8", decimals)),
abiEncode.GetABIEncoded(new ABIValue("uint256", supply))
];
return new Aggregate3OutputDTO
{
ReturnData = [
new Result { ReturnData = abiEncode.GetABIEncoded(new ABIValue("string", name)) },
new Result { ReturnData = abiEncode.GetABIEncoded(new ABIValue("string", symbol)) },
new Result { ReturnData = abiEncode.GetABIEncoded(new ABIValue("uint8", decimals)) },
new Result { ReturnData = abiEncode.GetABIEncoded(new ABIValue("uint256", supply)) }
]
};
}
}
Loading