WalletConnect / WalletConnectSharp

A C# implementation of the WalletConnect client
Apache License 2.0
139 stars 60 forks source link

how swap from WalletConnectSharp to pancakeswap #198

Open MassoudKargar opened 2 weeks ago

MassoudKargar commented 2 weeks ago

Hello, how can I use WalletConnectSharp in csharp swap? I have written this code, but in the OnRequestEthGetTransactionReceiptWrapper method, after sending the information to the rpc from pancakeswap, I get this error.

Swap failed: Unknown error: "An unknown RPC error occurred.". Try increasing your slippage tolerance.

Can you help me?


@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

Home

Hello, world!
@if (dataset) { }
Welcome to your new app.
https://github.com/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; }
}
skibitsky commented 2 weeks ago

Hey @MassoudKargar,

In the OnRequestEthGetTransactionReceiptWrapper you don't need await engin.Respond.... Just assign your response to requestData.Response.

You can find documentation on how to respond to the session requests here.

We also offer an official lab that you can use to test your wallet. It's simpler than dapps such as PancakeSwap, making it a good starting point.

MassoudKargar commented 1 week ago

After completing the transaction, I get this error, but I don't understand why, can you help me?

MassoudKargar commented 1 week ago

this error

Swap failed: Unknown error: "Request expired. Please try again.". Try increasing your slippage tolerance.

image

skibitsky commented 1 week ago

I don't know how PancakeSwap handles connections and errors. It's a third-party app. Could you please use our official lab for testing?