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
105 changes: 104 additions & 1 deletion Thirdweb.Tests/Thirdweb.Utils/Thirdweb.Utils.Tests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Numerics;
using Newtonsoft.Json.Linq;

namespace Thirdweb.Tests.Utilities;

Expand Down Expand Up @@ -506,7 +507,7 @@ public async void ToJsonExternalWalletFriendly_ReturnsCorrectValue4()
var verifyingContract = await pkWallet.GetAddress(); // doesn't matter here
var typedDataRaw = EIP712.GetTypedDefinition_SmartAccount_AccountMessage("Account", "1", 137, verifyingContract);
var json = Utils.ToJsonExternalWalletFriendly(typedDataRaw, msg);
var jsonObject = Newtonsoft.Json.Linq.JObject.Parse(json);
var jsonObject = JObject.Parse(json);
var internalMsg = jsonObject.SelectToken("$.message.message");
Assert.NotNull(internalMsg);
Assert.Equal("0x01020304", internalMsg);
Expand Down Expand Up @@ -763,4 +764,106 @@ public async Task FetchGasFees_Celo()
Assert.True(maxPrio > 0);
Assert.Equal(maxFee, maxPrio);
}

[Fact]
public void PreprocessTypedDataJson_FormatsBigIntegers()
{
// Arrange
var inputJson =
/*lang=json,strict*/
@"
{
""from"": 973250616940336452028326648501327235277017847475,
""data"": ""0x"",
""nested"": {
""value"": 4294967295
},
""array"": [
123,
973250616940336452028326648501327235277017847475
]
}";

var expectedJson =
/*lang=json,strict*/
@"
{
""from"": ""973250616940336452028326648501327235277017847475"",
""data"": ""0x"",
""nested"": {
""value"": 4294967295
},
""array"": [
123,
""973250616940336452028326648501327235277017847475""
]
}";

// Act
var processedJson = Utils.PreprocessTypedDataJson(inputJson);

// Assert
var expectedJObject = JObject.Parse(expectedJson);
var processedJObject = JObject.Parse(processedJson);

Assert.Equal(expectedJObject, processedJObject);
}

[Fact]
public void PreprocessTypedDataJson_NoLargeNumbers_NoChange()
{
// Arrange
var inputJson =
/*lang=json,strict*/
@"
{
""value"": 123,
""nested"": {
""value"": 456
},
""array"": [1, 2, 3]
}";

// Act
var processedJson = Utils.PreprocessTypedDataJson(inputJson);
var expectedJObject = JObject.Parse(inputJson);
var processedJObject = JObject.Parse(processedJson);

// Assert
Assert.Equal(expectedJObject, processedJObject);
}

[Fact]
public void PreprocessTypedDataJson_NestedLargeNumbers()
{
// Arrange
var inputJson =
/*lang=json,strict*/
@"
{
""nested"": {
""value"": 973250616940336452028326648501327235277017847475
},
""array"": [123, 973250616940336452028326648501327235277017847475]
}";

var expectedJson =
/*lang=json,strict*/
@"
{
""nested"": {
""value"": ""973250616940336452028326648501327235277017847475""
},
""array"": [123, ""973250616940336452028326648501327235277017847475""]
}";

// Act
var processedJson = Utils.PreprocessTypedDataJson(inputJson);

// Assert
var expectedJObject = JObject.Parse(expectedJson);
var processedJObject = JObject.Parse(processedJson);

Assert.Equal(expectedJObject, processedJObject);
}
}
50 changes: 50 additions & 0 deletions Thirdweb/Thirdweb.Utils/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -953,4 +953,54 @@ public static async Task<SocialProfiles> GetSocialProfiles(ThirdwebClient client

return new SocialProfiles(deserializedResponse.Data);
}

/// <summary>
/// Preprocesses the typed data JSON to stringify large numbers.
/// </summary>
/// <param name="json">The typed data JSON.</param>
/// <returns>The preprocessed typed data JSON.</returns>
public static string PreprocessTypedDataJson(string json)
{
var jObject = JObject.Parse(json);

static void StringifyLargeNumbers(JToken token)
{
if (token is JObject obj)
{
foreach (var property in obj.Properties().ToList())
{
StringifyLargeNumbers(property.Value);
}
}
else if (token is JArray array)
{
foreach (var item in array.ToList())
{
StringifyLargeNumbers(item);
}
}
else if (token is JValue value)
{
if (value.Type == JTokenType.Integer)
{
try
{
var bigInt = BigInteger.Parse(value.ToString());
if (bigInt > new BigInteger(uint.MaxValue) || bigInt < BigInteger.Zero)
{
value.Replace(bigInt.ToString());
}
}
catch (FormatException)
{
// Skip if the value isn't properly formatted as an integer
}
}
}
}

StringifyLargeNumbers(jObject);

return jObject.ToString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -776,9 +776,11 @@ public async Task<string> SignTypedDataV4(string json)
throw new ArgumentNullException(nameof(json), "Json to sign cannot be null.");
}

var processedJson = Utils.PreprocessTypedDataJson(json);

var url = $"{ENCLAVE_PATH}/sign-typed-data";

var requestContent = new StringContent(json, Encoding.UTF8, "application/json");
var requestContent = new StringContent(processedJson, Encoding.UTF8, "application/json");

var response = await this.HttpClient.PostAsync(url, requestContent).ConfigureAwait(false);
_ = response.EnsureSuccessStatusCode();
Expand Down
Loading