-
Notifications
You must be signed in to change notification settings - Fork 62
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for using Nethereum for EIP-712 serialization. Upgrade Nethereum to 4.8.0
- Loading branch information
1 parent
a4824c8
commit 945e139
Showing
16 changed files
with
407 additions
and
111 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
using System.Numerics; | ||
using System.Diagnostics; | ||
using Nethereum.ABI.FunctionEncoding.Attributes; | ||
using Nethereum.Signer.EIP712; | ||
using Newtonsoft.Json; | ||
using WalletConnectSharp.Core.Models; | ||
using WalletConnectSharp.Core.Models.Ethereum.Types; | ||
using WalletConnectSharp.Desktop; | ||
using WalletConnectSharp.NEthereum; | ||
using Nethereum.ABI.EIP712; | ||
|
||
namespace WalletConnectSharp.Examples.Examples; | ||
|
||
[Struct("Message")] | ||
public class Message | ||
{ | ||
[EvmType("string", "stringValue", 1)] | ||
[JsonProperty("stringValue", Order = 1)] | ||
[Parameter("string", "stringValue", 1)] | ||
public string StringValue { get; set; } | ||
|
||
[EvmType("address", "addressValue", 2)] | ||
[JsonProperty("addressValue", Order = 2)] | ||
[Parameter("address", "addressValue", 2)] | ||
public string AddressValue { get; set; } | ||
|
||
[EvmType("uint8", "uint8Value", 3)] | ||
[JsonProperty("uint8Value", Order = 3)] | ||
[Parameter("uint8", "uint8Value", 3)] | ||
public ushort Uint8Value { get; set; } | ||
|
||
[EvmType("uint64", "uint64Value", 4)] | ||
[JsonProperty("uint64Value", Order = 4)] | ||
[Parameter("uint64", "uint64Value", 4)] | ||
public ulong Uint64Value { get; set; } | ||
|
||
[EvmType("uint256", "uint256Value", 5)] | ||
[JsonProperty("uint256Value", Order = 5)] | ||
[Parameter("uint256", "uint256Value", 5)] | ||
public ulong Uint256Value { get; set; } | ||
} | ||
|
||
/// <summary> | ||
/// Example demonstrating different methods to sign typed data. | ||
/// </summary> | ||
public class SignTypedDataExample : IExample | ||
{ | ||
|
||
public string Name => "sign_typed_data_example"; | ||
|
||
public const string VerifyingContractName = "Some Contract Name"; | ||
public const string VerifyingContractVersion = "1.0"; | ||
public static BigInteger VerifyingContractChainId => new(1); | ||
public const string VerifyingContractAddress = "0x0000000000000000000000000000000000000000"; | ||
|
||
public static EIP712Domain WalletConnectDomain => new() | ||
{ | ||
Name = VerifyingContractName, | ||
Version = VerifyingContractVersion, | ||
ChainId = VerifyingContractChainId, | ||
VerifyingContract = VerifyingContractAddress | ||
}; | ||
|
||
public static Domain NethereumDomain => new() | ||
{ | ||
Name = VerifyingContractName, | ||
Version = VerifyingContractVersion, | ||
ChainId = VerifyingContractChainId, | ||
VerifyingContract = VerifyingContractAddress | ||
}; | ||
|
||
public TypedData<Domain> NethereumSchema => new() | ||
{ | ||
Domain = NethereumDomain, | ||
Types = MemberDescriptionFactory.GetTypesMemberDescription( | ||
typeof(Domain), | ||
typeof(Message) | ||
), | ||
PrimaryType = nameof(Message), | ||
}; | ||
|
||
private static Eip712TypedDataSigner _signer => new(); | ||
|
||
|
||
public async Task Execute(string[] args) | ||
{ | ||
// create client metadata | ||
var clientMeta = new ClientMeta() | ||
{ | ||
Name = "WalletConnectSharp", | ||
Description = "An example that showcases how to use the WalletConnectSharp library", | ||
Icons = new[] { "https://app.warriders.com/favicon.ico" }, | ||
URL = "https://app.warriders.com/" | ||
}; | ||
|
||
// create a client | ||
var client = new WalletConnect(clientMeta); | ||
|
||
Console.WriteLine("Connect using the following URL"); | ||
Console.WriteLine(client.URI); | ||
|
||
await client.Connect(); | ||
|
||
var account = Nethereum.Util.AddressUtil.Current.ConvertToChecksumAddress(client.Accounts[0]); | ||
|
||
Console.WriteLine("The account " + account + " has connected!"); | ||
|
||
// create a message to sign | ||
var message = new Message | ||
{ | ||
StringValue = "Some String", | ||
AddressValue = account, | ||
Uint8Value = 123, | ||
Uint64Value = 12345, | ||
Uint256Value = 123456, | ||
}; | ||
|
||
try | ||
{ | ||
await Sign_With_WalletConnect_Serialization(client, account, message); | ||
await Sign_With_Nethereum_Serialization(client, account, message); | ||
} | ||
catch (Exception ex) | ||
{ | ||
Console.WriteLine(ex); | ||
} | ||
finally | ||
{ | ||
await client.Disconnect(); | ||
} | ||
|
||
Console.WriteLine($"{Name}: COMPLETE!"); | ||
} | ||
|
||
private async Task Sign_With_WalletConnect_Serialization(WalletConnect client, string account, Message message) | ||
{ | ||
Console.WriteLine($"Requesting Signature from {account}"); | ||
|
||
var signature = await client.EthSignTypedData(account, message, WalletConnectDomain); | ||
|
||
Console.WriteLine($"WalletConnect signature: {signature}"); | ||
|
||
var recovered = _signer.RecoverFromSignatureV4( | ||
message, NethereumSchema, signature); | ||
|
||
Console.WriteLine($"WalletConnect recovered: {recovered}"); | ||
|
||
// assert the recovery matches the account | ||
Debug.Assert(recovered == account); | ||
} | ||
|
||
private async Task Sign_With_Nethereum_Serialization(WalletConnect client, string account, Message message) | ||
{ | ||
Console.WriteLine($"Requesting WC Signature from {account}"); | ||
|
||
var signature = await client.EthSignTypedData(account, message, NethereumSchema); | ||
|
||
Console.WriteLine($"Nethereum signature: {signature}"); | ||
|
||
var recovered = _signer.RecoverFromSignatureV4( | ||
message, NethereumSchema, signature); | ||
|
||
Console.WriteLine($"Nethereum recovered: {recovered}"); | ||
|
||
// assert the recovery matches the account | ||
Debug.Assert(recovered == account); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 24 additions & 0 deletions
24
WalletConnectSharp.Core/Extensions/DictionaryExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
|
||
namespace WalletConnectSharp.Core.Extensions; | ||
|
||
public static class DictionaryExtensions | ||
{ | ||
/// <Summary> | ||
/// Try to add the element to the dictionary if the key does not already exist. | ||
/// </Summary> | ||
public static bool TryAdd<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TValue value) | ||
{ | ||
if (dictionary == null) | ||
{ | ||
throw new ArgumentNullException(nameof(dictionary)); | ||
} | ||
|
||
if (!dictionary.ContainsKey(key)) | ||
{ | ||
dictionary.Add(key, value); | ||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
} |
36 changes: 24 additions & 12 deletions
36
WalletConnectSharp.Core/Models/Ethereum/Types/EIP712Domain.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,35 @@ | ||
using WalletConnectSharp.Core.Models.Ethereum.Types; | ||
using System.Numerics; | ||
|
||
namespace WalletConnectSharp.Core.Models; | ||
namespace WalletConnectSharp.Core.Models.Ethereum.Types; | ||
|
||
public class EIP712Domain | ||
{ | ||
public string name; | ||
public string version; | ||
[EvmType("string", "name", 1)] | ||
[JsonProperty("name", Order = 1)] | ||
public virtual string Name { get; set; } | ||
|
||
[EvmIgnore] | ||
public int chainId; | ||
[EvmType("string", "version", 2)] | ||
[JsonProperty("version", Order = 2)] | ||
public virtual string Version { get; set; } | ||
|
||
[EvmType("address")] | ||
public string verifyingContract; | ||
[EvmType("uint256", "chainId", 3)] | ||
[JsonProperty("chainId", Order = 3)] | ||
public virtual BigInteger? ChainId { get; set; } | ||
|
||
[EvmType("address", "verifyingContract", 4)] | ||
[JsonProperty("verifyingContract", Order = 4)] | ||
public virtual string VerifyingContract { get; set; } | ||
|
||
public EIP712Domain() | ||
{ | ||
|
||
} | ||
|
||
public EIP712Domain(string name, string version, int chainId, string verifyingContract) | ||
{ | ||
this.name = name; | ||
this.version = version; | ||
this.chainId = chainId; | ||
this.verifyingContract = verifyingContract; | ||
Name = name; | ||
Version = version; | ||
ChainId = chainId; | ||
VerifyingContract = verifyingContract; | ||
} | ||
} |
14 changes: 11 additions & 3 deletions
14
WalletConnectSharp.Core/Models/Ethereum/Types/EvmTypeAttribute.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,18 @@ | ||
namespace WalletConnectSharp.Core.Models.Ethereum.Types; | ||
|
||
[AttributeUsage(AttributeTargets.Property)] | ||
public class EvmTypeAttribute : Attribute | ||
{ | ||
public string TypeName { get; } | ||
public string Type { get; } | ||
|
||
public string Name { get; } | ||
|
||
public int Order { get; } | ||
|
||
public EvmTypeAttribute(string typename) | ||
public EvmTypeAttribute(string typename, string name = null, int order = 1) | ||
{ | ||
TypeName = typename; | ||
Type = typename; | ||
Name = name; | ||
Order = order; | ||
} | ||
} |
Oops, something went wrong.