Skip to content

Commit 1a737cf

Browse files
committed
Support Tuple Deserialization into Arrays & Lists
1 parent 0ccfbca commit 1a737cf

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

Thirdweb.Tests/Thirdweb.Contracts/Thirdweb.Contracts.Tests.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,26 @@ public async Task PrepareTest_NoSig()
102102
Assert.Contains("Method signature not found in contract ABI.", exception.Message);
103103
}
104104

105+
[Fact(Timeout = 120000)]
106+
public async Task ReadTest_TupleIntoArray()
107+
{
108+
var contract = await ThirdwebContract.Create(this.Client, "0xEb4AAB0253a50918a2Cbb7ADBaab78Ad19C07Bb1", 421614);
109+
var result = await contract.Read<List<object>>("getReserves");
110+
Assert.NotNull(result);
111+
Assert.NotEmpty(result);
112+
Assert.True(result.Count == 3);
113+
}
114+
115+
[Fact(Timeout = 120000)]
116+
public async Task ReadTest_TupleIntoList()
117+
{
118+
var contract = await ThirdwebContract.Create(this.Client, "0xEb4AAB0253a50918a2Cbb7ADBaab78Ad19C07Bb1", 421614);
119+
var result = await contract.Read<List<object>>("getReserves");
120+
Assert.NotNull(result);
121+
Assert.NotEmpty(result);
122+
Assert.True(result.Count == 3);
123+
}
124+
105125
private sealed class AllowlistProof
106126
{
107127
public List<byte[]> Proof { get; set; } = new List<byte[]>();

Thirdweb/Thirdweb.Contracts/ThirdwebContract.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
using System.Numerics;
2+
using Nethereum.ABI.FunctionEncoding;
3+
using Nethereum.ABI.Model;
24
using Nethereum.Contracts;
35
using Nethereum.Hex.HexTypes;
6+
using Newtonsoft.Json;
47

58
namespace Thirdweb;
69

@@ -119,7 +122,18 @@ public static async Task<T> Read<T>(ThirdwebContract contract, string method, pa
119122
var data = function.GetData(parameters);
120123
var resultData = await rpc.SendRequestAsync<string>("eth_call", new { to = contract.Address, data }, "latest").ConfigureAwait(false);
121124

122-
return function.DecodeTypeOutput<T>(resultData);
125+
if ((typeof(T).IsGenericType && typeof(T).GetGenericTypeDefinition() == typeof(List<>)) || typeof(T).IsArray)
126+
{
127+
var functionAbi = contractRaw.ContractBuilder.ContractABI.FindFunctionABIFromInputData(data);
128+
var outputList = new FunctionCallDecoder().DecodeDefaultData(resultData.HexToBytes(), functionAbi.OutputParameters);
129+
var resultList = outputList.Select(x => x.Result).ToList();
130+
var json = JsonConvert.SerializeObject(resultList);
131+
return JsonConvert.DeserializeObject<T>(json);
132+
}
133+
else
134+
{
135+
return function.DecodeTypeOutput<T>(resultData);
136+
}
123137
}
124138

125139
/// <summary>

0 commit comments

Comments
 (0)