Skip to content

Commit

Permalink
Improve default session update and address processing
Browse files Browse the repository at this point in the history
  • Loading branch information
skibitsky committed Mar 19, 2024
1 parent 8aa8f82 commit badf504
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 55 deletions.
81 changes: 58 additions & 23 deletions WalletConnectSharp.Sign/Controllers/AddressProvider.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
using Newtonsoft.Json;
using WalletConnectSharp.Common.Logging;
using WalletConnectSharp.Sign.Interfaces;
using WalletConnectSharp.Sign.Interfaces;
using WalletConnectSharp.Sign.Models;
using WalletConnectSharp.Sign.Models.Engine.Events;

namespace WalletConnectSharp.Sign.Controllers;

public class AddressProvider : IAddressProvider
{
private bool _disposed;

public struct DefaultData
{
public SessionStruct Session;
Expand Down Expand Up @@ -91,7 +91,7 @@ public AddressProvider(ISignClient client)
// set the first connected session to the default one
client.SessionConnected += ClientOnSessionConnected;
client.SessionDeleted += ClientOnSessionDeleted;
client.SessionUpdated += ClientOnSessionUpdated;
client.SessionUpdateRequest += ClientOnSessionUpdated;
client.SessionApproved += ClientOnSessionConnected;
}

Expand Down Expand Up @@ -119,6 +119,7 @@ private async void ClientOnSessionUpdated(object sender, SessionEvent e)
{
if (DefaultSession.Topic == e.Topic)
{
DefaultSession = Sessions.Get(e.Topic);
await UpdateDefaultChainIdAndNamespaceAsync();
}
}
Expand Down Expand Up @@ -180,20 +181,27 @@ private async Task UpdateDefaultChainIdAndNamespaceAsync()
}
}

public Caip25Address CurrentAddress(string @namespace = null, SessionStruct session = default)
{
@namespace ??= DefaultNamespace;
if (string.IsNullOrWhiteSpace(session.Topic)) // default
session = DefaultSession;

return session.CurrentAddress(@namespace);
}

public async Task InitAsync()
{
await this.LoadDefaults();
}

public async Task SetDefaultNamespaceAsync(string @namespace)
{
if (string.IsNullOrWhiteSpace(@namespace))
{
throw new ArgumentNullException(nameof(@namespace));
}

if (!DefaultSession.Namespaces.ContainsKey(@namespace))
{
throw new InvalidOperationException($"Namespace {@namespace} is not available in the current session");
}

DefaultNamespace = @namespace;
await SaveDefaults();
}

public async Task SetDefaultChainIdAsync(string chainId)
{
if (string.IsNullOrWhiteSpace(chainId))
Expand All @@ -210,25 +218,52 @@ public async Task SetDefaultChainIdAsync(string chainId)
await SaveDefaults();
}

public Caip25Address[] AllAddresses(string @namespace = null, SessionStruct session = default)
public Caip25Address CurrentAddress(string chainId = null, SessionStruct session = default)
{
chainId ??= DefaultChainId;
if (string.IsNullOrWhiteSpace(session.Topic))
{
session = DefaultSession;
}

return session.CurrentAddress(chainId);
}

public IEnumerable<Caip25Address> AllAddresses(string @namespace = null, SessionStruct session = default)
{
@namespace ??= DefaultNamespace;
if (string.IsNullOrWhiteSpace(session.Topic)) // default
session = DefaultSession;

return session.AllAddresses(@namespace);
}

public void Dispose()
{
_client.SessionConnected -= ClientOnSessionConnected;
_client.SessionDeleted -= ClientOnSessionDeleted;
_client.SessionUpdated -= ClientOnSessionUpdated;
_client.SessionApproved -= ClientOnSessionConnected;
Dispose(true);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if (_disposed)
{
return;
}

if (disposing)
{
_client.SessionConnected -= ClientOnSessionConnected;
_client.SessionDeleted -= ClientOnSessionDeleted;
_client.SessionUpdateRequest -= ClientOnSessionUpdated;
_client.SessionApproved -= ClientOnSessionConnected;

_client = null;
Sessions = null;
DefaultNamespace = null;
DefaultSession = default;
}

_client = null;
Sessions = null;
DefaultNamespace = null;
DefaultSession = default;
_disposed = true;
}
}
7 changes: 5 additions & 2 deletions WalletConnectSharp.Sign/Interfaces/IAddressProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@ public interface IAddressProvider : IModule

ISession Sessions { get; }

Caip25Address CurrentAddress(string @namespace = null, SessionStruct session = default);

Task InitAsync();

Task SetDefaultNamespaceAsync(string @namespace);

Task SetDefaultChainIdAsync(string chainId);

Caip25Address[] AllAddresses(string @namespace = null, SessionStruct session = default);
Caip25Address CurrentAddress(string chainId = null, SessionStruct session = default);

IEnumerable<Caip25Address> AllAddresses(string @namespace = null, SessionStruct session = default);
}
86 changes: 56 additions & 30 deletions WalletConnectSharp.Sign/Models/SessionStruct.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,51 +82,77 @@ public string Key
return Topic;
}
}
public Caip25Address CurrentAddress(string @namespace)

public Caip25Address CurrentAddress(string chainId)
{
// double check
if (@namespace == null)
throw new ArgumentException("SessionStruct.CurrentAddress: @namespace is null");
if (string.IsNullOrWhiteSpace(Topic))
throw new ArgumentException("SessionStruct.CurrentAddress: Session is undefined");

var defaultNamespace = Namespaces[@namespace];
ValidateChainIdAndTopic(chainId);

var namespaceStr = chainId.Split(':')[0];

if (!Namespaces.TryGetValue(namespaceStr, out var defaultNamespace))
{
throw new InvalidOperationException(
$"SessionStruct.CurrentAddress: Given namespace {namespaceStr} is not available in the current session");
}

if (defaultNamespace.Accounts.Length == 0)
throw new Exception(
$"SessionStruct.CurrentAddress: Given namespace {@namespace} has no connected addresses");
throw new InvalidOperationException(
$"SessionStruct.CurrentAddress: Given namespace {namespaceStr} has no connected addresses");

var fullAddress = defaultNamespace.Accounts[0];
var addressParts = fullAddress.Split(":");
var fullAddress = Array.Find(defaultNamespace.Accounts, addr => addr.StartsWith(chainId));
if (fullAddress == default)
{
throw new InvalidOperationException(
$"SessionStruct.CurrentAddress: No address found for chain {chainId}");
}

var address = fullAddress.Split(":")[2];
return new Caip25Address { Address = address, ChainId = chainId };
}

public IEnumerable<Caip25Address> AllAddresses(string @namespace)
{
ValidateNamespaceAndTopic(@namespace);

var defaultNamespace = Namespaces[@namespace];
return defaultNamespace.Accounts.Length == 0
? []
: defaultNamespace.Accounts.Select(CreateCaip25Address);
}

public static Caip25Address CreateCaip25Address(string fullAddress)
{
var addressParts = fullAddress.Split(":");
var address = addressParts[2];
var chainId = string.Join(':', addressParts.Take(2));

return new Caip25Address()
{
Address = address,
ChainId = chainId,
};
return new Caip25Address { Address = address, ChainId = chainId };
}
public Caip25Address[] AllAddresses(string @namespace)

private void ValidateNamespaceAndTopic(string @namespace)
{
// double check
if (@namespace == null)
throw new ArgumentException("SessionStruct.AllAddresses: @namespace is null");
{
throw new ArgumentException("@namespace is null");
}

if (string.IsNullOrWhiteSpace(Topic))
throw new ArgumentException("SessionStruct.AllAddresses: Session is undefined");

var defaultNamespace = Namespaces[@namespace];
{
throw new ArgumentException("Session is undefined");
}
}

if (defaultNamespace.Accounts.Length == 0)
return null; //The namespace {@namespace} has no addresses connected")
private void ValidateChainIdAndTopic(string chainId)
{
if (chainId == null)
{
throw new ArgumentException("chainId is null");
}

return defaultNamespace.Accounts.Select(addr => new Caip25Address()
if (string.IsNullOrWhiteSpace(Topic))
{
Address = addr.Split(":")[2], ChainId = string.Join(":", addr.Split(":").Take(2))
}).ToArray();
throw new ArgumentException("Session is undefined");
}
}
}
}

0 comments on commit badf504

Please sign in to comment.