Skip to content

Commit

Permalink
Merge pull request #185 from WalletConnect/chore/pairing-topic-in-con…
Browse files Browse the repository at this point in the history
…necteddata

chore: include pairing topic in ConnectedData and connection optimisation
  • Loading branch information
skibitsky authored Apr 15, 2024
2 parents e3597b6 + 936624b commit 585ed2f
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 54 deletions.
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<DefaultVersion>2.3.2</DefaultVersion>
<DefaultVersion>2.3.3</DefaultVersion>
<DefaultTargetFrameworks>net6.0;net7.0;net8.0;netstandard2.1;</DefaultTargetFrameworks>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
Expand Down
91 changes: 55 additions & 36 deletions WalletConnectSharp.Sign/Engine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ public async Task<ConnectedData> Connect(ConnectOptions options)
var sessionProperties = options.SessionProperties;
var relays = options.Relays;
var topic = options.PairingTopic;
string uri = "";
var uri = string.Empty;
var active = false;

if (!string.IsNullOrEmpty(topic))
Expand All @@ -428,30 +428,59 @@ public async Task<ConnectedData> Connect(ConnectOptions options)

if (string.IsNullOrEmpty(topic) || !active)
{
var CreatePairing = await this.Client.Core.Pairing.Create();
topic = CreatePairing.Topic;
uri = CreatePairing.Uri;
var newPairing = await Client.Core.Pairing.Create();
topic = newPairing.Topic;
uri = newPairing.Uri;
}

var publicKey = await this.Client.Core.Crypto.GenerateKeyPair();
var proposal = new SessionPropose()
{
RequiredNamespaces = requiredNamespaces,
Relays = relays != null
? new[] { relays }
: new[] { new ProtocolOptions() { Protocol = RelayProtocols.Default } },
? [relays]
: [new ProtocolOptions() { Protocol = RelayProtocols.Default }],
Proposer = new Participant() { PublicKey = publicKey, Metadata = this.Client.Metadata },
OptionalNamespaces = optionalNamespaces,
SessionProperties = sessionProperties,
};

TaskCompletionSource<SessionStruct> approvalTask = new TaskCompletionSource<SessionStruct>();
this.SessionConnected += async (sender, session) =>

SessionConnected += OnSessionConnected;
SessionConnectionErrored += OnSessionConnectionErrored;

if (string.IsNullOrWhiteSpace(topic))
{
throw WalletConnectException.FromType(ErrorType.NO_MATCHING_KEY, $"connect() pairing topic: {topic}");
}

var id = await MessageHandler.SendRequest<SessionPropose, SessionProposeResponse>(topic, proposal);

var expiry = Clock.CalculateExpiry(options.Expiry);

await PrivateThis.SetProposal(id, new ProposalStruct()
{
logger.Log("Got session_connect event for session struct");
Expiry = expiry,
Id = id,
Proposer = proposal.Proposer,
Relays = proposal.Relays,
RequiredNamespaces = proposal.RequiredNamespaces,
OptionalNamespaces = proposal.OptionalNamespaces,
SessionProperties = proposal.SessionProperties
});

return new ConnectedData(uri, topic, approvalTask.Task);

async void OnSessionConnected(object sender, SessionStruct session)
{
if (session.PairingTopic != topic)
{
return;
}

if (approvalTask.Task.IsCompleted)
{
logger.Log("approval already received though, skipping");
return;
}

Expand All @@ -462,44 +491,32 @@ public async Task<ConnectedData> Connect(ConnectOptions options)

if (!string.IsNullOrWhiteSpace(topic))
{
await this.Client.Core.Pairing.UpdateMetadata(topic, session.Peer.Metadata);
await Client.Core.Pairing.UpdateMetadata(topic, session.Peer.Metadata);
}

SessionConnected -= OnSessionConnected;
SessionConnectionErrored -= OnSessionConnectionErrored;

approvalTask.SetResult(completeSession);
};
}

this.SessionConnectionErrored += (sender, exception) =>
void OnSessionConnectionErrored(object sender, Exception exception)
{
if (approvalTask.Task.IsCompleted)
{
return;
}

if (exception == null)
{
return;
approvalTask.SetException(exception);
};

if (string.IsNullOrWhiteSpace(topic))
{
throw WalletConnectException.FromType(ErrorType.NO_MATCHING_KEY, $"connect() pairing topic: {topic}");
}

var id = await MessageHandler.SendRequest<SessionPropose, SessionProposeResponse>(topic, proposal);

var expiry = Clock.CalculateExpiry(options.Expiry);
}

await PrivateThis.SetProposal(id, new ProposalStruct()
{
Expiry = expiry,
Id = id,
Proposer = proposal.Proposer,
Relays = proposal.Relays,
RequiredNamespaces = proposal.RequiredNamespaces,
OptionalNamespaces = proposal.OptionalNamespaces,
SessionProperties = proposal.SessionProperties,
});
SessionConnected -= OnSessionConnected;
SessionConnectionErrored -= OnSessionConnectionErrored;

return new ConnectedData() { Uri = uri, Approval = approvalTask.Task };
approvalTask.SetException(exception);
}
}

/// <summary>
Expand Down Expand Up @@ -569,7 +586,8 @@ public async Task<IApprovedData> Approve(ApproveParams @params)
Relay = new ProtocolOptions() { Protocol = relayProtocol ?? "irn" },
Namespaces = namespaces,
Controller = new Participant() { PublicKey = selfPublicKey, Metadata = this.Client.Metadata },
Expiry = Clock.CalculateExpiry(SessionExpiry)
Expiry = Clock.CalculateExpiry(SessionExpiry),
PairingTopic = pairingTopic
};

await this.Client.Core.Relayer.Subscribe(sessionTopic);
Expand All @@ -595,6 +613,7 @@ public async Task<IApprovedData> Approve(ApproveParams @params)
Expiry = sessionSettle.Expiry,
Namespaces = sessionSettle.Namespaces,
Relay = sessionSettle.Relay,
PairingTopic = pairingTopic,
RequiredNamespaces = requiredNamespaces,
};

Expand Down
37 changes: 20 additions & 17 deletions WalletConnectSharp.Sign/Models/Engine/ConnectedData.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
using System.Threading.Tasks;
namespace WalletConnectSharp.Sign.Models.Engine;

namespace WalletConnectSharp.Sign.Models.Engine
/// <summary>
/// A class that representing a pending session proposal. Includes a URI that can be given to a
/// wallet app out-of-band and an Approval Task that can be awaited.
/// </summary>
public class ConnectedData(string uri, string pairingTopic, Task<SessionStruct> approval)
{
/// <summary>
/// A class that representing a pending session proposal. Includes a URI that can be given to a
/// wallet app out-of-band and an Approval Task that can be awaited.
/// The URI that can be used to retrieve the submitted session proposal. This should be shared
/// SECURELY out-of-band to a wallet supporting the SDK.
/// </summary>
public class ConnectedData
{
/// <summary>
/// The URI that can be used to retrieve the submitted session proposal. This should be shared
/// SECURELY out-of-band to a wallet supporting the SDK
/// </summary>
public string Uri;
public string Uri { get; private set; } = uri;

/// <summary>
/// A task that will resolve to an approved session. If the session proposal is rejected, then this
/// task will throw an exception.
/// </summary>
public Task<SessionStruct> Approval;
}
/// <summary>
/// Pairing is a topic encrypted by a symmetric key shared through a URI between two clients with
/// the sole purpose of communicating session proposals.
/// </summary>
public string PairingTopic { get; private set; } = pairingTopic;

/// <summary>
/// A task that will resolve to an approved session. If the session proposal is rejected, then this
/// task will throw an exception.
/// </summary>
public Task<SessionStruct> Approval { get; private set; } = approval;
}

0 comments on commit 585ed2f

Please sign in to comment.