Skip to content

Commit

Permalink
Merge pull request #193 from WalletConnect/fix/session-request-events…
Browse files Browse the repository at this point in the history
…-json-error

fix: SessionRequestEvents json error
  • Loading branch information
skibitsky authored May 9, 2024
2 parents 2b7647a + b2ae9e4 commit e8389ee
Show file tree
Hide file tree
Showing 4 changed files with 215 additions and 25 deletions.
177 changes: 177 additions & 0 deletions Tests/WalletConnectSharp.Sign.Test/SignTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,62 @@ public class TestRequest2
public int y;
}

// represents array of strings requests, similar to personal_sign
[RpcMethod("complex_test_method")] [RpcRequestOptions(Clock.ONE_MINUTE, 99990)]
public class ComplexTestRequest : List<string>
{
public ComplexTestRequest()
{
}

public ComplexTestRequest(params string[] args) : base(args)
{
}

public int A
{
get
{
if (Count != 2 || !int.TryParse(this[0], out var a))
{
return 0;
}

return a;
}
}

public int B
{
get
{
if (Count != 2 || !int.TryParse(this[1], out var b))
{
return 0;
}

return b;
}
}
}

// represents array of objects requests, similar to eth_sendTransaction
[RpcMethod("complex_test_method_2")] [RpcRequestOptions(Clock.ONE_MINUTE, 99991)] [RpcResponseOptions(Clock.ONE_MINUTE, 99992)]
public class ComplexTestRequest2 : List<TestRequest2>
{
public ComplexTestRequest2()
{
}

public ComplexTestRequest2(params TestRequest2[] args) : base(args)
{
}

public string X => this.FirstOrDefault()?.x ?? string.Empty;

public int Y => this.FirstOrDefault()?.y ?? -1;
}

[RpcResponseOptions(Clock.ONE_MINUTE, 99999)]
public class TestResponse
{
Expand Down Expand Up @@ -387,6 +443,127 @@ public async Task TestTwoUniqueSessionRequestResponse()

Assert.True(responseReturned2);
}

[Fact] [Trait("Category", "integration")]
public async Task TestTwoUniqueComplexSessionRequestResponse()
{
await _cryptoFixture.WaitForClientsReady();

var testAddress = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045";
var testMethod = "complex_test_method";
var testMethod2 = "complex_test_method_2";

var dappConnectOptions = new ConnectOptions()
{
RequiredNamespaces = new RequiredNamespaces()
{
{
"eip155", new ProposedNamespace()
{
Methods = new[]
{
testMethod,
testMethod2
},
Chains = new[]
{
"eip155:1",
"eip155:10"
},
Events = new[]
{
"chainChanged",
"accountsChanged"
}
}
}
}
};

var dappClient = ClientA;
var connectData = await dappClient.Connect(dappConnectOptions);

var walletClient = ClientB;
var proposal = await walletClient.Pair(connectData.Uri);

var approveData = await walletClient.Approve(proposal, testAddress);

var sessionData = await connectData.Approval;
await approveData.Acknowledged();

var rnd = new Random();
var a = rnd.Next(100);
var b = rnd.Next(100);
var x = rnd.NextStrings(AllowedChars, (Math.Min(a, b), Math.Max(a, b)), 1).First();
var y = x.Length;

var testData = new ComplexTestRequest(a.ToString(), b.ToString());
var testData2 = new ComplexTestRequest2(new TestRequest2()
{
x = x, y = y
});

var pending = new TaskCompletionSource<int>();

// Step 1. Setup event listener for request

// The wallet client will listen for the request with the "test_method" rpc method
walletClient.Engine.SessionRequestEvents<ComplexTestRequest, TestResponse>()
.OnRequest += (requestData) =>
{
var request = requestData.Request;
var data = request.Params;
requestData.Response = new TestResponse()
{
result = data.A * data.B
};
return Task.CompletedTask;
};

// The wallet client will listen for the request with the "test_method" rpc method
walletClient.Engine.SessionRequestEvents<ComplexTestRequest2, bool>()
.OnRequest += (requestData) =>
{
var request = requestData.Request;
var data = request.Params;
requestData.Response = data.X.Length == data.Y;
return Task.CompletedTask;
};

// The dapp client will listen for the response
// Normally, we wouldn't do this and just rely on the return value
// from the dappClient.Engine.Request function call (the response Result or throws an Exception)
// We do it here for the sake of testing
dappClient.Engine.SessionRequestEvents<ComplexTestRequest, TestResponse>()
.FilterResponses((r) => r.Topic == sessionData.Topic)
.OnResponse += (responseData) =>
{
var response = responseData.Response;
var data = response.Result;
pending.TrySetResult(data.result);
return Task.CompletedTask;
};

// 2. Send the request from the dapp client
var responseReturned = await dappClient.Engine.Request<ComplexTestRequest, TestResponse>(sessionData.Topic, testData);
var responseReturned2 = await dappClient.Engine.Request<ComplexTestRequest2, bool>(sessionData.Topic, testData2);

// 3. Wait for the response from the event listener
var eventResult = await pending.Task.WithTimeout(TimeSpan.FromSeconds(5));

Assert.Equal(eventResult, a * b);
Assert.Equal(eventResult, testData.A * testData.B);
Assert.Equal(eventResult, responseReturned.result);

Assert.True(responseReturned2);
}

[Fact, Trait("Category", "integration")]
public async Task TestTwoUniqueSessionRequestResponseUsingAddressProviderDefaults()
Expand Down
31 changes: 20 additions & 11 deletions WalletConnectSharp.Core/Controllers/TypedMessageHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,23 +98,32 @@ public async Task<DisposeHandlerToken> HandleMessageType<T, TR>(Func<string, Jso

async void RequestCallback(object sender, MessageEvent e)
{
if (requestCallback == null || Disposed)
try
{
return;
}
if (requestCallback == null || Disposed)
{
return;
}

var topic = e.Topic;
var message = e.Message;
var topic = e.Topic;
var message = e.Message;

var options = DecodeOptionForTopic(topic);

if (options == null && !await this.Core.Crypto.HasKeys(topic)) return;
var options = DecodeOptionForTopic(topic);

if (options == null && !await Core.Crypto.HasKeys(topic))
{
return;
}

var payload = await this.Core.Crypto.Decode<JsonRpcRequest<T>>(topic, message, options);
var payload = await Core.Crypto.Decode<JsonRpcRequest<T>>(topic, message, options);

(await this.Core.History.JsonRpcHistoryOfType<T, TR>()).Set(topic, payload, null);
(await Core.History.JsonRpcHistoryOfType<T, TR>()).Set(topic, payload, null);

await requestCallback(topic, payload);
await requestCallback(topic, payload);
}
catch (JsonException)
{
}
}

async void ResponseCallback(object sender, MessageEvent e)
Expand Down
31 changes: 17 additions & 14 deletions WalletConnectSharp.Core/Models/Verify/Verifier.cs
Original file line number Diff line number Diff line change
@@ -1,35 +1,38 @@
using System.Net;
using Newtonsoft.Json;
using WalletConnectSharp.Common.Utils;
using Newtonsoft.Json;
using WalletConnectSharp.Common.Logging;

namespace WalletConnectSharp.Core.Models.Verify;

public class Verifier
public sealed class Verifier : IDisposable
{
public const string VerifyServer = "https://verify.walletconnect.com";

public CancellationTokenSource CancellationTokenSource { get; }
private const string VerifyServer = "https://verify.walletconnect.com";

public Verifier()
private readonly HttpClient _client = new()
{
this.CancellationTokenSource = new CancellationTokenSource(Clock.AsTimeSpan(Clock.FIVE_SECONDS));
}
Timeout = TimeSpan.FromSeconds(5)
};

public async Task<string> Resolve(string attestationId)
{
try
{
using HttpClient client = new HttpClient();
var url = $"{VerifyServer}/attestation/{attestationId}";
var results = await client.GetStringAsync(url);
WCLogger.Log($"[Verifier] Resolving attestation {attestationId} from {url}");
var results = await _client.GetStringAsync(url);
WCLogger.Log($"[Verifier] Resolved attestation. Results: {results}");

var verifiedContext = JsonConvert.DeserializeObject<VerifiedContext>(results);

return verifiedContext != null ? verifiedContext.Origin : "";
return verifiedContext != null ? verifiedContext.Origin : string.Empty;
}
catch
{
return "";
return string.Empty;
}
}

public void Dispose()
{
_client?.Dispose();
}
}
1 change: 1 addition & 0 deletions WalletConnectSharp.Core/WalletConnectCore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ protected virtual void Dispose(bool disposing)
MessageHandler?.Dispose();
Expirer?.Dispose();
Pairing?.Dispose();
Verify?.Dispose();
}

Disposed = true;
Expand Down

0 comments on commit e8389ee

Please sign in to comment.