Closed MassoudKargar closed 3 weeks ago
Hey @MassoudKargar,
Thank you for the PR! Could you please explain what exact issue it solves? The map is statically initialized, so I'm curious about the conditions that result in the null reference.
I was programming an inter-voltage connection that I wrote myself with a dapp exchange like pancakeswap, and when I received the eth_sendTransaction event, I was getting an error and I couldn't continue, and the system didn't react at all, that's why I started debugging your system and realized the problem. I think it is because of the new system of Asp .net 8 about
I am trying to understand why the map is null for you. It is automatically initialized with an empty dictionary when an instance of the Store
object is created, even before Init()
is called. The map is set to null only in the Dispose()
method. This makes me think that you are trying to access the store after it has been disposed.
While your suggestion fixes the error message, you may encounter more issues later because you are operating on a disposed Store
.
Could you share your code or explain how you initialize the SDK and handle session requests?
I am programming in blazor webassembly application
And I get this error
Debugging hotkey: Shift+Alt+D (when application has focus)
[MONO] /w/1/s/src/mono/mono/metadata/icall.c:6177 2[[System.Int64, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[WalletConnectSharp.Sign.Models.PendingRequestStruct, WalletConnectSharp.Sign, Version=2.3.7.0, Culture=neutral, PublicKeyToken=null]].Set(Int64 key, PendingRequestStruct value) at WalletConnectSharp.Sign.Engine.WalletConnectSharp.Sign.Interfaces.IEnginePrivate.SetPendingSessionRequest(PendingRequestStruct pendingRequest) at WalletConnectSharp.Sign.Models.SessionRequestEventHandler
2.1[[BlazorApp1.Pages.Home.EthGetTransactionReceiptWrapper, BlazorApp1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], WalletConnectSharp.Sign, Version=2.3.7.0, Culture=neutral, PublicKeyToken=null],[BlazorApp1.Pages.Home.EthSignTransactionResponse, BlazorApp1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].MoveNext() at WalletConnectSharp.Core.Controllers.TypedMessageHandler.<>c__DisplayClass18_0
2.<
And this is my code
@page "/" @using Newtonsoft.Json @using WalletConnectSharp.Common.Utils @using WalletConnectSharp.Network.Models @using WalletConnectSharp.Sign @using WalletConnectSharp.Sign.Models @using WalletConnectSharp.Sign.Models.Engine.Events @using WalletConnectSharp.Storage
@if (dataset) { <input type="text" @bind="@Uri" @bind:event="oninput" @bind:after="OnConnectUrl" /> }
Welcome to your new app. @code { public string? Uri { get; set; } public static string? Uris { get; set; } static readonly string words = "...."; Wallet? wallet; static Account? account; WalletConnectSignClient? client; ProposalStruct? proposalStruct; Engine? engin; bool dataset; public Dictionary<int, string>? ChainList { get; set; } } @functions { protected override async Task OnInitializedAsync() { ChainList = new Dictionary<int, string>() { { 56, "https://binance.llamarpc.com" }, { 97, "https://endpoints.omniatech.io/v1/bsc/testnet/public" }, { 11155111, "https://endpoints.omniatech.io/v1/eth/sepolia/public" }, }; dataset = false; await InitData(); }
private async Task InitData()
{
wallet = new Wallet(words, null);
account = wallet.GetAccount(0);
var dappOptions = new SignClientOptions()
{
ProjectId = "....",
Metadata = new Metadata()
{
Description = "An example dapp to showcase WalletConnectSharpv2",
Icons = new[] { "https://walletconnect.com/meta/favicon.ico" },
Name = "WalletConnectSharpv2 Dapp Example",
Url = "https://walletconnect.com",
},
Storage = new InMemoryStorage(),
Name = "my-app",
};
client = await WalletConnectSignClient.Init(dappOptions);
dataset = true;
}
public async Task OnConnectUrl()
{
if (client != null)
{
try
{
client.PendingRequests.Dispose();
client.SessionProposed += SessionProposed;
proposalStruct = await client.Pair(Uri);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
private async void SessionProposed(object? sender, SessionProposalEvent e)
{
string[]? manespacesMethods = e.Proposal.OptionalNamespaces.Values.Select(s => s.Methods).FirstOrDefault();
engin = sender as Engine;
if (engin != null && client != null && account != null)
{
engin.SessionRequestEvents<EthGetTransactionReceiptWrapper, EthSignTransactionResponse>().OnRequest += OnRequestEthGetTransactionReceiptWrapper;
var approveData = await client.Approve(e.Proposal, new[] { account.Address });
await approveData.Acknowledged();
}
}
private async Task OnRequestEthGetTransactionReceiptWrapper(RequestEventArgs<EthGetTransactionReceiptWrapper, EthSignTransactionResponse> requestData)
{
try
{
var chainId = int.Parse(client.AddressProvider.DefaultChainId.Split(':')[1]);
var ethGetTransaction = requestData.Request.Params.FirstOrDefault();
var account = new Account(Home.account.PrivateKey);
Web3 web3 = new(new Account(account.PrivateKey), url: ChainList[chainId]) { TransactionManager = { UseLegacyAsDefault = true, } };
var tx = new TransactionInput()
{
Data = ethGetTransaction.Data,
From = ethGetTransaction.From,
To = ethGetTransaction.To,
Gas = new HexBigInteger(ethGetTransaction.Gas),
Value = new HexBigInteger(ethGetTransaction.Value),
ChainId = new HexBigInteger($"0x{chainId}")
};
var receipt = await web3.Eth.TransactionManager.TransactionReceiptService.DeployContractAndWaitForReceiptAsync(tx);
await engin.Respond<EthGetTransactionReceiptWrapper, EthSignTransactionResponse>(requestData.Topic, new JsonRpcResponse<EthSignTransactionResponse>(requestData.Request.Id, new Error(), new EthSignTransactionResponse(receipt)));
requestData.Response = receipt;
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
[RpcResponseOptions(Clock.ONE_MINUTE, 99999)]
[JsonConverter(typeof(ConvertToStr<TransactionReceipt>))]
public class EthSignTransactionResponse
{
private readonly TransactionReceipt _response;
public EthSignTransactionResponse(TransactionReceipt response)
{
_response = response;
}
public static implicit operator EthSignTransactionResponse(TransactionReceipt response)
{
if (response == null)
return null;
return new EthSignTransactionResponse(response);
}
public override string ToString()
{
return _response.BlockHash;
}
}
public class ConvertToStr<T> : JsonConverter where T : class
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(string) || objectType == typeof(T);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
// Deserialize the value as usual
return serializer.Deserialize<string>(reader) as T;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value.ToString());
}
}
[RpcMethod("eth_sendTransaction"), RpcRequestOptions(Clock.ONE_MINUTE, 99999)]
public class EthGetTransactionReceiptWrapper : List<EthGetTransaction?>
{
}
public class EthGetTransaction
{
[JsonProperty("from")]
public string? From { get; set; }
[JsonProperty("to")]
public string? To { get; set; }
[JsonProperty("data")]
public string? Data { get; set; }
[JsonProperty("gas")]
public string? Gas { get; set; }
[JsonProperty("value")]
public string? Value { get; set; }
}
}
@MassoudKargar I believe the issue might be in your OnConnectUrl
method, specifically with disposing client.PendingRequests
. You should dispose the client when it is no longer needed and don't dispose individual parts of the client.
I did not understand exactly, can you give me a sample code or give an example please?
@MassoudKargar from your code:
public async Task OnConnectUrl()
{
if (client != null)
{
try
{
client.PendingRequests.Dispose(); // ← REMOVE
client.SessionProposed += SessionProposed;
proposalStruct = await client.Pair(Uri);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
Thanks, the problem is solved, but I don't remember why I used such a code. But I have another problem and thank you for your help. I have a problem with the response for the OnRequestEthGetTransactionReceiptWrapper method for the eth_sendTransaction event. Is it possible for you to give me an example? I get this error on pancakeswap.finance service
Swap failed: Unknown error: "Request expired. Please try again.". Try increasing your slippage tolerance. Dismiss
@MassoudKargar could you please open an issue? In the issue please specify if you're building a wallet or an app.
…re method Set property map