From 54a5e4403f047f68235afb50a6bc1e38e33fb661 Mon Sep 17 00:00:00 2001 From: Quinn Purdy Date: Wed, 13 Dec 2023 11:11:54 -0500 Subject: [PATCH] Fix IsValidMessageSignature request and respective tests. --- .../Scripts/MockTokenContentFetcher.cs | 8 +++++++- .../Scripts/MockTransactionDetailsFetcher.cs | 8 +++++++- Assets/SequenceSDK/Ethereum/Chain.cs | 3 +++ Assets/SequenceSDK/Ethereum/ChainId.cs | 2 +- Assets/SequenceSDK/Ethereum/Tests/WalletTests.cs | 4 ++-- .../Ethereum/Utils/ByteArrayExtensions.cs | 7 ++++++- Assets/SequenceSDK/Ethereum/Wallet/EthWallet.cs | 6 +++--- Assets/SequenceSDK/Ethereum/Wallet/IWallet.cs | 4 +--- .../ParameterTypes/IsValidMessageSignatureArgs.cs | 6 +++--- .../DataTypes/ParameterTypes/SignMessageArgs.cs | 13 +++++++++++-- Assets/SequenceSDK/WaaS/HttpClient.cs | 7 ++++++- .../WaaS/Tests/WaaSToWalletAdapterTests.cs | 5 +++-- Assets/SequenceSDK/WaaS/Tests/WaaSWalletTests.cs | 9 +++------ Assets/SequenceSDK/WaaS/WaaSToWalletAdapter.cs | 4 ++-- Assets/SequenceSDK/WaaS/WaaSWallet.cs | 5 +++-- 15 files changed, 61 insertions(+), 30 deletions(-) diff --git a/Assets/SequenceExamples/Scripts/MockTokenContentFetcher.cs b/Assets/SequenceExamples/Scripts/MockTokenContentFetcher.cs index f8ea8874..5a2323e6 100644 --- a/Assets/SequenceExamples/Scripts/MockTokenContentFetcher.cs +++ b/Assets/SequenceExamples/Scripts/MockTokenContentFetcher.cs @@ -51,11 +51,17 @@ public TokenElement CreateMockElement() Sprite tokenIconSprite = Sprite.Create(tokenIconTexture, new Rect(0, 0, tokenIconTexture.width, tokenIconTexture.height), new Vector2(.5f, .5f)); + Chain network = Chain.None; + while (network == Chain.None) + { + network = EnumExtensions.GetRandomEnumValue(); + } + return new TokenElement( new ERC20(potentialMockAddresses.GetRandomObjectFromArray()), tokenIconSprite, potentialNames.GetRandomObjectFromArray(), - EnumExtensions.GetRandomEnumValue(), + network, (uint)Random.Range(0, 10000), potentialSymbols.GetRandomObjectFromArray(), new MockCurrencyConverter()); diff --git a/Assets/SequenceExamples/Scripts/MockTransactionDetailsFetcher.cs b/Assets/SequenceExamples/Scripts/MockTransactionDetailsFetcher.cs index b4475bed..4899927e 100644 --- a/Assets/SequenceExamples/Scripts/MockTransactionDetailsFetcher.cs +++ b/Assets/SequenceExamples/Scripts/MockTransactionDetailsFetcher.cs @@ -97,8 +97,14 @@ private TransactionDetails CreateMockElement(string contractAddress = null) contract = new Address(contractAddress); } + Chain network = Chain.None; + while (network == Chain.None) + { + network = EnumExtensions.GetRandomEnumValue(); + } + return new TransactionDetails(potentialTypes.GetRandomObjectFromArray(), - EnumExtensions.GetRandomEnumValue(), + network, tokenIconSprite, contract, new Address(potentialMockAddresses.GetRandomObjectFromArray()), diff --git a/Assets/SequenceSDK/Ethereum/Chain.cs b/Assets/SequenceSDK/Ethereum/Chain.cs index 00f5bd4f..2a9cc8e9 100644 --- a/Assets/SequenceSDK/Ethereum/Chain.cs +++ b/Assets/SequenceSDK/Ethereum/Chain.cs @@ -23,5 +23,8 @@ public enum Chain TestnetArbitrumGoerli = 421613, TestnetBNBSmartChain = 97, TestnetBaseGoerli = 84531, + + // Null + None = 0 } } \ No newline at end of file diff --git a/Assets/SequenceSDK/Ethereum/ChainId.cs b/Assets/SequenceSDK/Ethereum/ChainId.cs index 5756f385..303c1004 100644 --- a/Assets/SequenceSDK/Ethereum/ChainId.cs +++ b/Assets/SequenceSDK/Ethereum/ChainId.cs @@ -5,7 +5,7 @@ namespace Sequence { public static class ChainId { - public static string AsString(this Chain chain) + public static string AsHexString(this Chain chain) { BigInteger chainId = (BigInteger)(int)chain; return chainId.BigIntegerToHexString(); diff --git a/Assets/SequenceSDK/Ethereum/Tests/WalletTests.cs b/Assets/SequenceSDK/Ethereum/Tests/WalletTests.cs index 5b292a30..7d0b7d9a 100644 --- a/Assets/SequenceSDK/Ethereum/Tests/WalletTests.cs +++ b/Assets/SequenceSDK/Ethereum/Tests/WalletTests.cs @@ -272,10 +272,10 @@ public async Task TestWalletSignMessageWithChainId(IWallet wallet, string messag string address = wallet.GetAddress(); Assert.NotNull(address); - string sig = await wallet.SignMessage(message, "0x89"); + string sig = await wallet.SignMessage(message, Chain.Polygon.AsHexString()); Assert.NotNull(sig); - bool valid = await wallet.IsValidSignature(sig, message, chainId: "0x89"); + bool valid = await wallet.IsValidSignature(sig, message, chain: Chain.Polygon); Assert.IsTrue(valid); } diff --git a/Assets/SequenceSDK/Ethereum/Utils/ByteArrayExtensions.cs b/Assets/SequenceSDK/Ethereum/Utils/ByteArrayExtensions.cs index 1b5a717a..8af31d65 100644 --- a/Assets/SequenceSDK/Ethereum/Utils/ByteArrayExtensions.cs +++ b/Assets/SequenceSDK/Ethereum/Utils/ByteArrayExtensions.cs @@ -7,7 +7,12 @@ public static class ByteArrayExtensions { public static string ByteArrayToHexStringWithPrefix(this byte[] byteArray) { - return "0x" + SequenceCoder.ByteArrayToHexString(byteArray); + return "0x" + byteArray.ByteArrayToHexString(); + } + + public static string ByteArrayToHexString(this byte[] byteArray) + { + return SequenceCoder.ByteArrayToHexString(byteArray); } public static bool HasPrefix(this byte[] b, byte[] prefix) { diff --git a/Assets/SequenceSDK/Ethereum/Wallet/EthWallet.cs b/Assets/SequenceSDK/Ethereum/Wallet/EthWallet.cs index ccfbf700..62803b71 100644 --- a/Assets/SequenceSDK/Ethereum/Wallet/EthWallet.cs +++ b/Assets/SequenceSDK/Ethereum/Wallet/EthWallet.cs @@ -212,12 +212,12 @@ public string SignByteArray(string privateKey, byte[] byteArray) /// The signature to verify. /// The message that was signed. /// true if the signature is valid, false otherwise. - public async Task IsValidSignature(string signature, string message, string chainId = "", uint accountIndex = 0) + public async Task IsValidSignature(string signature, string message, Chain chain = Chain.None) { byte[] messageBytes = Encoding.UTF8.GetBytes(message); - if (chainId != null && chainId.Length > 0) + if (chain != Chain.None) { - messageBytes = ByteArrayExtensions.ConcatenateByteArrays(messageBytes, Encoding.UTF8.GetBytes(chainId)); + messageBytes = ByteArrayExtensions.ConcatenateByteArrays(messageBytes, Encoding.UTF8.GetBytes(chain.AsHexString())); } byte[] messagePrefix = PrefixedMessage(messageBytes); byte[] hashedMessage = SequenceCoder.KeccakHash(messagePrefix); diff --git a/Assets/SequenceSDK/Ethereum/Wallet/IWallet.cs b/Assets/SequenceSDK/Ethereum/Wallet/IWallet.cs index 8483fad6..704c0760 100644 --- a/Assets/SequenceSDK/Ethereum/Wallet/IWallet.cs +++ b/Assets/SequenceSDK/Ethereum/Wallet/IWallet.cs @@ -57,9 +57,7 @@ public Task SendTransactionBatchAndWaitForReceipts(IEthCli /// /// /// true if the signature is valid, false otherwise. - public Task IsValidSignature(string signature, string message, string chainId = "", uint accountIndex = 0); - - + public Task IsValidSignature(string signature, string message, Chain chain = Chain.None); /// /// Recovers the Ethereum address from a message and its signature. diff --git a/Assets/SequenceSDK/WaaS/DataTypes/ParameterTypes/IsValidMessageSignatureArgs.cs b/Assets/SequenceSDK/WaaS/DataTypes/ParameterTypes/IsValidMessageSignatureArgs.cs index ad86c252..3abe8d35 100644 --- a/Assets/SequenceSDK/WaaS/DataTypes/ParameterTypes/IsValidMessageSignatureArgs.cs +++ b/Assets/SequenceSDK/WaaS/DataTypes/ParameterTypes/IsValidMessageSignatureArgs.cs @@ -3,14 +3,14 @@ namespace Sequence.WaaS [System.Serializable] public class IsValidMessageSignatureArgs { - public uint chainId; + public string chainId; public string walletAddress; public string message; public string signature; - public IsValidMessageSignatureArgs(uint chainId, string walletAddress, string message, string signature) + public IsValidMessageSignatureArgs(Chain chain, string walletAddress, string message, string signature) { - this.chainId = chainId; + this.chainId = ((int)chain).ToString(); this.walletAddress = walletAddress; this.message = message; this.signature = signature; diff --git a/Assets/SequenceSDK/WaaS/DataTypes/ParameterTypes/SignMessageArgs.cs b/Assets/SequenceSDK/WaaS/DataTypes/ParameterTypes/SignMessageArgs.cs index f15f09d6..9cbe7bf4 100644 --- a/Assets/SequenceSDK/WaaS/DataTypes/ParameterTypes/SignMessageArgs.cs +++ b/Assets/SequenceSDK/WaaS/DataTypes/ParameterTypes/SignMessageArgs.cs @@ -1,4 +1,8 @@ using System; +using System.Text; +using Sequence.ABI; +using Sequence.Extensions; +using Sequence.Utils; using SequenceSDK.WaaS; namespace Sequence.WaaS @@ -18,7 +22,7 @@ public SignMessageArgs(string wallet, Chain network, string message, uint timeBe int networkId = (int)network; this.wallet = wallet; this.network = networkId.ToString(); - this.message = message; + this.message = PrepareMessage(message); this.issued = (uint)DateTimeOffset.UtcNow.ToUnixTimeSeconds(); this.expires = this.issued + timeBeforeExpiry; } @@ -27,9 +31,14 @@ public SignMessageArgs(string wallet, string networkId, string message, uint tim { this.wallet = wallet; this.network = networkId; - this.message = message; + this.message = PrepareMessage(message); this.issued = (uint)DateTimeOffset.UtcNow.ToUnixTimeSeconds(); this.expires = this.issued + timeBeforeExpiry; } + + private static string PrepareMessage(string message) + { + return Wallet.IWallet.PrefixedMessage(Encoding.UTF8.GetBytes(message)).ByteArrayToHexString().ToUpper().EnsureHexPrefix(); + } } } \ No newline at end of file diff --git a/Assets/SequenceSDK/WaaS/HttpClient.cs b/Assets/SequenceSDK/WaaS/HttpClient.cs index 3a6943ee..dcb2875c 100644 --- a/Assets/SequenceSDK/WaaS/HttpClient.cs +++ b/Assets/SequenceSDK/WaaS/HttpClient.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using JetBrains.Annotations; using Newtonsoft.Json; +using Sequence.Authentication; using Sequence.Provider; using UnityEngine; using UnityEngine.Networking; @@ -32,9 +33,13 @@ public void AddDefaultHeader(string key, string value) this._defaultHeaders[key] = value; } - public async Task SendRequest(string path, T args, [CanBeNull] Dictionary headers = null) + public async Task SendRequest(string path, T args, [CanBeNull] Dictionary headers = null, string overrideUrl = null) { string url = _url + "/" + path; + if (overrideUrl != null) + { + url = overrideUrl.AppendTrailingSlashIfNeeded() + path; + } string requestJson = JsonConvert.SerializeObject(args, serializerSettings); UnityWebRequest request = UnityWebRequest.Get(url); request.SetRequestHeader("Content-Type", "application/json"); diff --git a/Assets/SequenceSDK/WaaS/Tests/WaaSToWalletAdapterTests.cs b/Assets/SequenceSDK/WaaS/Tests/WaaSToWalletAdapterTests.cs index 822adfbe..6f11a19c 100644 --- a/Assets/SequenceSDK/WaaS/Tests/WaaSToWalletAdapterTests.cs +++ b/Assets/SequenceSDK/WaaS/Tests/WaaSToWalletAdapterTests.cs @@ -56,9 +56,10 @@ public async Task TestSignMessage_withAdapter(string message, Chain network) try { WaaSTestHarness.TestStarted?.Invoke(); - string signature = await _wallet.SignMessage(message, network.AsString()); + string signature = await _wallet.SignMessage(message, network.AsHexString()); CustomAssert.NotNull(signature, nameof(TestSignMessage_withAdapter), message, network); - CustomAssert.IsTrue(WaaSWalletTests.AppearsToBeValidSignature(signature), nameof(TestSignMessage_withAdapter), message, network); // If a signature appears valid and comes from WaaS, it most likely is valid - validity is tested on the WaaS side + bool isValid = await _wallet.IsValidSignature(signature, message, network); + CustomAssert.IsTrue(isValid, nameof(TestSignMessage_withAdapter), message, network); WaaSTestHarness.TestPassed?.Invoke(); } catch (Exception e) diff --git a/Assets/SequenceSDK/WaaS/Tests/WaaSWalletTests.cs b/Assets/SequenceSDK/WaaS/Tests/WaaSWalletTests.cs index 4b694cbd..d995a5b1 100644 --- a/Assets/SequenceSDK/WaaS/Tests/WaaSWalletTests.cs +++ b/Assets/SequenceSDK/WaaS/Tests/WaaSWalletTests.cs @@ -52,7 +52,9 @@ public async Task TestMessageSigning(string message, Chain network) var result = await _wallet.SignMessage(new SignMessageArgs(_address, network, message)); string signature = result.signature; CustomAssert.NotNull(signature, nameof(TestMessageSigning), message, network); - CustomAssert.IsTrue(AppearsToBeValidSignature(signature), nameof(TestMessageSigning), message, network); // If a signature appears valid and comes from WaaS, it most likely is valid - validity is tested on the WaaS side + var isValid = await _wallet.IsValidMessageSignature(new IsValidMessageSignatureArgs(network, _address, message, signature)); + bool isValidSignature = isValid.isValid; + CustomAssert.IsTrue(isValidSignature, nameof(TestMessageSigning), message, network); WaaSTestHarness.TestPassed?.Invoke(); } catch (Exception e) @@ -61,11 +63,6 @@ public async Task TestMessageSigning(string message, Chain network) } } - public static bool AppearsToBeValidSignature(string signature) - { - return signature.StartsWith("0x") && signature.IsHexFormat(); - } - public async Task TestTransfer() { try diff --git a/Assets/SequenceSDK/WaaS/WaaSToWalletAdapter.cs b/Assets/SequenceSDK/WaaS/WaaSToWalletAdapter.cs index e3e37f6f..e500b863 100644 --- a/Assets/SequenceSDK/WaaS/WaaSToWalletAdapter.cs +++ b/Assets/SequenceSDK/WaaS/WaaSToWalletAdapter.cs @@ -113,9 +113,9 @@ public async Task SignMessage(string message, string chainId) return result.signature; } - public async Task IsValidSignature(string signature, string message, string chainId, uint accountIndex = 0) + public async Task IsValidSignature(string signature, string message, Chain chain) { - var args = new IsValidMessageSignatureArgs((uint)chainId.HexStringToInt(), GetAddress(), message, signature); + var args = new IsValidMessageSignatureArgs(chain, GetAddress(), message, signature); var result = await _wallet.IsValidMessageSignature(args); return result.isValid; } diff --git a/Assets/SequenceSDK/WaaS/WaaSWallet.cs b/Assets/SequenceSDK/WaaS/WaaSWallet.cs index 5e21b439..ca0e8237 100644 --- a/Assets/SequenceSDK/WaaS/WaaSWallet.cs +++ b/Assets/SequenceSDK/WaaS/WaaSWallet.cs @@ -37,9 +37,10 @@ public async Task SignMessage(SignMessageArgs args) return result; } - public Task IsValidMessageSignature(IsValidMessageSignatureArgs args) // Todo figure out this intent is still supported + public Task IsValidMessageSignature(IsValidMessageSignatureArgs args) { - return _intentSender.SendIntent(args); + return _httpClient.SendRequest( + "API/IsValidMessageSignature", args, null, "https://api.sequence.app/rpc/"); } public event Action OnSendTransactionComplete;