Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error with Toggle chain sample when you switch back to the original chain with Metamask on WebGL #1262 #1263

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 59 additions & 22 deletions src/ChainSafe.Gaming.Reown/ReownProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,11 @@ void OnPublishedMessage(object sender, PublishParams args)
}
}

public override Task SwitchChain(IChainConfig chain)
{
return SwitchChainAddIfMissing(chain);
}

private WalletModel GetSessionWallet()
{
var nativeUrl = RemoveSlash(session.Peer.Metadata.Url);
Expand Down Expand Up @@ -501,11 +506,6 @@ private string GetPlayerAddress()
return GetFullAddress().Split(":")[2];
}

private string ExtractChainIdFromAddress()
{
return string.Join(":", GetFullAddress().Split(":").Take(2));
}

private string GetFullAddress()
{
var defaultChain = session.Namespaces.Keys.FirstOrDefault();
Expand All @@ -527,23 +527,6 @@ private string GetFullAddress()

private async Task<T> ReownRequest<T>(string topic, string method, params object[] parameters)
{
// Helper method to make a request using ReownSignClient.
async Task<T> MakeRequest<TRequest>(bool sendChainId = true)
{
var data = (TRequest)Activator.CreateInstance(typeof(TRequest), parameters);
try
{
return await SignClient.Request<TRequest, T>(
topic,
data,
sendChainId ? BuildChainIdForReown(chainConfig.ChainId) : null);
}
catch (KeyNotFoundException e)
{
throw new ReownIntegrationException("Can't execute request. The session was most likely terminated on the wallet side.", e);
}
}

switch (method)
{
case "personal_sign":
Expand Down Expand Up @@ -578,6 +561,60 @@ async Task<T> MakeRequest<TRequest>(bool sendChainId = true)
throw new ReownIntegrationException($"{method} RPC method currently not implemented.", e);
}
}

// Helper method to make a request using ReownSignClient.
async Task<T> MakeRequest<TRequest>(bool sendChainId = true)
{
var data = (TRequest)Activator.CreateInstance(typeof(TRequest), parameters);
try
{
var chainIdParameter = sendChainId ? BuildChainIdForReown(chainConfig.ChainId) : null;
return await SignClient.Request<TRequest, T>(topic, data, chainIdParameter);
}
catch (KeyNotFoundException e)
{
throw new ReownIntegrationException("Can't execute request. The session was most likely terminated on the wallet side.", e);
}
}
}

private async Task SwitchChainAddIfMissing(IChainConfig config = null)
{
var chainId = await GetWalletChainId();
var chainConfig = config ?? this.chainConfig;

// If we are already on the correct network, return.
if (chainId == chainConfig.ChainId)
{
return;
}

var addChainParameter = new
{
chainId = "0x" + ulong.Parse(chainConfig.ChainId).ToString("X"),
chainName = chainConfig.Chain,
nativeCurrency = new
{
name = chainConfig.NativeCurrency.Name,
symbol = chainConfig.NativeCurrency.Symbol,
decimals = chainConfig.NativeCurrency.Decimals,
},
rpcUrls = new[] { chainConfig.Rpc },
blockExplorerUrls = new[] { chainConfig.BlockExplorerUrl },
};

using (operationTracker.TrackOperation($"Switching the network to: {chainConfig.Chain}...\n(The network will be added if it's missing)"))
{
try
{
// this will switch to the network and add it to the wallet if it's missing
await Request<object[]>("wallet_addEthereumChain", addChainParameter);
}
catch (Exception e)
{
throw new InvalidOperationException("Failed to add or switch to the network.", e);
}
}
}
}
}
8 changes: 7 additions & 1 deletion src/ChainSafe.Gaming/Web3/Evm/Wallet/IWalletProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ public interface IWalletProvider : IRpcProvider
/// </summary>
/// <exception cref="InvalidOperationException">Throwing exception if we fail to switch to the network.</exception>
/// <returns>Nothing.</returns>
Task SwitchChainAddIfMissing(IChainConfig chainConfig = null);
Task SwitchChain(IChainConfig chainConfig = null);

/// <summary>
/// Fetches the current Chain ID of the connected wallet.
/// </summary>
/// <returns>The current Chain ID of the connected wallet.</returns>
Task<string> GetWalletChainId();
}
}
48 changes: 8 additions & 40 deletions src/ChainSafe.Gaming/Web3/Evm/Wallet/WalletProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,7 @@ public async Task HandleChainSwitching()
}
}

private async Task SwitchChain(IChainConfig chainId)
{
await SwitchChainAddIfMissing(chainId);
}

private async Task<string> GetWalletChainId()
public virtual async Task<string> GetWalletChainId()
{
var rawHexChainId = await Request<string>(
"eth_chainId");
Expand All @@ -65,44 +60,17 @@ private async Task<string> GetWalletChainId()
return number.ToString(CultureInfo.InvariantCulture);
}

public async Task SwitchChainAddIfMissing(IChainConfig config = null)
public virtual async Task SwitchChain(IChainConfig chain)
{
var chainId = await GetWalletChainId();
var chainConfig = config ?? this.chainConfig;

// If we are already on the correct network, return.
if (chainId == chainConfig.ChainId)
chain ??= chainConfig;
var str = $"{BigInteger.Parse(chain.ChainId):X}";
str = str.TrimStart('0');
var networkSwitchParams = new
{
return;
}

var addChainParameter = new
{
chainId = "0x" + ulong.Parse(chainConfig.ChainId).ToString("X"),
chainName = chainConfig.Chain,
nativeCurrency = new
{
name = chainConfig.NativeCurrency.Name,
symbol = chainConfig.NativeCurrency.Symbol,
decimals = chainConfig.NativeCurrency.Decimals,
},
rpcUrls = new[] { chainConfig.Rpc },
blockExplorerUrls = new[] { chainConfig.BlockExplorerUrl },
chainId = $"0x{str}", // Convert the Chain ID to hex format
};

using (operationTracker.TrackOperation($"Switching the network to: {chainConfig.Chain}...\n(The network will be added if it's missing)"))
{
try
{
// this will switch to the network and add it to the wallet if it's missing
await Request<object[]>("wallet_addEthereumChain", addChainParameter);
}
catch (Exception e)
{
logWriter.LogError($"Failed to add or switch to the network: {e.Message}");
throw new InvalidOperationException("Failed to add or switch to the network.", e);
}
}
await Request<string>("wallet_switchEthereumChain", networkSwitchParams);
}
}
}
2 changes: 1 addition & 1 deletion src/ChainSafe.Gaming/Web3/Evm/Wallet/WalletSigner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public virtual async ValueTask WillStartAsync()

PublicAddress = address.AssertIsPublicAddress();

await walletProvider.SwitchChainAddIfMissing();
await walletProvider.SwitchChain();
}

public virtual async Task<string> SignMessage(string message)
Expand Down
Loading