magicblock-labs / Solana.Unity-SDK

Open-Source Unity-Solana SDK with Full RPC coverage, NFT support and more
https://solana.unity-sdk.gg
MIT License
156 stars 88 forks source link

Error when calling dex.GetSwapQuoteFromWhirpool() #98

Closed BlackDemonZyT closed 1 year ago

BlackDemonZyT commented 1 year ago

My code is:

                    WalletBase wallet = new SolanaWalletAdapterWebGL(options, RpcCluster.MainNet, "https://api.metaplex.solana.com/", null, true);
                    await wallet.Login();
                    dex = new OrcaDex(wallet.Account, wallet.ActiveRpcClient, commitment: Commitment.Finalized);

                    // GET ORCA SWAP PRICE
                    TokenData tokenA = await dex.GetTokenBySymbol("USDC");
                    TokenData tokenB = await dex.GetTokenByMint(item.Account.Data.Parsed.Info.Mint);
                    Pool whirlpool;
                    if (tokenA != null && tokenB != null)
                    {
                        whirlpool = await dex.FindWhirlpoolAddress(tokenA.MintAddress, tokenB.MintAddress);

                        if(whirlpool != null)
                        {
                            Debug.Log("whirlpool FOUND FOR " + item.Account.Data.Parsed.Info.Mint);
                            Debug.Log("DECIMALS IS " + tokenA.Decimals);
                            var value = float.Parse("1");
                            Debug.Log("CONVERTED TO LONG");

                         ->   SwapQuote swapQuote = await dex.GetSwapQuoteFromWhirlpool(
                                whirlpool.Address,
                                DecimalUtil.ToUlong(value, tokenA.Decimals),
                                tokenA.MintAddress,
                                slippageTolerance: 0.1
                            );

                            if(swapQuote != null)
                            {
                                Debug.Log("QUOTE found for " + item.Account.Data.Parsed.Info.Mint);
                                var quote = DecimalUtil.FromBigInteger(swapQuote.EstimatedAmountOut, tokenB.Decimals);
                                Debug.Log("PRICE OF " + item.Account.Data.Parsed.Info.Mint);
                                Debug.Log(quote);
                            }
                        }
                    }

But it fails in the marked line with this errors:

website.framework.js:3 InvalidOperationException: Sequence contains no matching element
  at System.Linq.Enumerable.First[TSource] (System.Collections.Generic.IEnumerable`1[T] source, System.Func`2[T,TResult] predicate) [0x00000] in <00000000000000000000000000000000>:0 
--- End of stack trace from previous location where exception was thrown ---

PercentageException: Conversion not possible
  at Solana.Unity.Dex.Math.Percentage.FromDouble (System.Double dValue) [0x00000] in <00000000000000000000000000000000>:0 
--- End of stack trace from previous location where exception was thrown ---
GabrielePicco commented 1 year ago

@BlackDemonZyT what's tokenB? If there is not direct poll on Orca for TokenA / TokenB, you won't be able to get a swap quote

BlackDemonZyT commented 1 year ago

@BlackDemonZyT what's tokenB? If there is not direct poll on Orca for TokenA / TokenB, you won't be able to get a swap quote

Token B is all tokens from the user, its in a loop, thats why i check after "if(whirpool != null)" so it only tries to get a quote for tokens that have whirlpool

GabrielePicco commented 1 year ago

I see, on which token are you getting the quote issue?

BlackDemonZyT commented 1 year ago

All of them, it does not work for any but it doesnt look like a get quote issue, it says Conversion.

GabrielePicco commented 1 year ago

@BlackDemonZyT can you please post an example of GetSwapQuoteFromWhirlpool call (you can hardcode the parameters) that make it fails for you?. With mint, decimals, value and whirlpool mint so that I can reproduce.

BlackDemonZyT commented 1 year ago

Look:

    public async void OnChangeInputA()
    {

        var inputAAmount = float.Parse(tokenInputA.text);
        TokenData tokenA = await dex.GetTokenBySymbol("USDC");
        TokenData tokenB = await dex.GetTokenBySymbol("KING");

        Pool _whirlpool = await dex.FindWhirlpoolAddress(tokenA.MintAddress, tokenB.MintAddress);
        BigInteger converted = DecimalUtil.ToUlong(inputAAmount, tokenA.Decimals);

        // AT THE TIME OF REACHING THIS METHOD, the variables are:
        // converted: 22000000
        // tokenB.MintAddress: 9noXzpXnkyEcKF3AeXqUHTdR59V5uvrRBUZ9bwfQwxeq
        // _whirlpool.Address: ARDj5ixvAYoviDc8eiJemh1rm5ALPWoSE9HYQBv6aLfq
        SwapQuote _swapQuote = await dex
                .GetSwapQuoteFromWhirlpool(_whirlpool.Address,                     -> ERROR ON THIS METHOD
                    converted,
                    tokenB.MintAddress);

        var quote = DecimalUtil.FromBigInteger(_swapQuote.EstimatedAmountOut, tokenB.Decimals);

        await MainThreadDispatcher.Instance().EnqueueAsync(() => {
            tokenInputB.text = quote.ToString(CultureInfo.InvariantCulture);
        });

        var tokenABalance = await Web3.Rpc.GetTokenBalanceByOwnerAsync(
                Web3.Account.PublicKey, tokenA.Mint);

        if (tokenABalance.Result == null || tokenABalance.Result.Value.AmountUlong < _swapQuote.EstimatedAmountIn)
        {
            tokenInputB.interactable = false;
        }
    }

The error:

PercentageException: Conversion not possible
  at Solana.Unity.Dex.Math.Percentage.FromDouble (System.Double dValue) [0x00000] in <00000000000000000000000000000000>:0 
--- End of stack trace from previous location where exception was thrown ---
BlackDemonZyT commented 1 year ago

Still happening

GabrielePicco commented 1 year ago

@BlackDemonZyT I'm not able to reproduce the issue, this is the code I tried:

  IDex dex = new OrcaDex(Web3.Account, Web3.Rpc, commitment: Commitment.Confirmed);
  TokenData tokenA = await dex.GetTokenBySymbol("USDC");
  TokenData tokenB = await dex.GetTokenBySymbol("KING");

  Pool _whirlpool = await dex.FindWhirlpoolAddress(tokenA.MintAddress, tokenB.MintAddress);

  var converted = DecimalUtil.ToUlong(2.0, tokenA.Decimals);

  // AT THE TIME OF REACHING THIS METHOD, the variables are:
  // converted: 2000000
  // tokenB.MintAddress: 9noXzpXnkyEcKF3AeXqUHTdR59V5uvrRBUZ9bwfQwxeq
  // _whirlpool.Address: ARDj5ixvAYoviDc8eiJemh1rm5ALPWoSE9HYQBv6aLfq
  var swapQuote = await dex
      .GetSwapQuoteFromWhirlpool(_whirlpool.Address, 
      converted,
      tokenA.MintAddress);

  var quote = DecimalUtil.FromBigInteger(swapQuote.EstimatedAmountOut, tokenB.Decimals);
  Debug.Log(quote);

I correctly see the quote for swapping 2 usdc for king

BlackDemonZyT commented 1 year ago

Which .NET version are you using in the project? I still have the same issue with the code you actually gave me.

BlackDemonZyT commented 1 year ago

Opened a repository with a simple project that gives the PercentageException

mywebsite.framework.js:10 PercentageException: Conversion not possible at Solana.Unity.Dex.Math.Percentage.FromDouble (System.Double dValue) [0x00000] in <00000000000000000000000000000000>:0 --- End of stack trace from previous location where exception was thrown ---

https://github.com/BlackDemonZyT/OrcaPercentageBug

You have to be running a web-server with HTTPS and domain (can be local domain) to try it so it does not fail CORS

GabrielePicco commented 1 year ago

@BlackDemonZyT thanks for creating the repo. Unfortunately I'm not able to reproduce your issue, tried with both .NET Framework and .NET standard 2.1 and a couple of different versions of Unity, both work without issues on my side and correctly display the quote:

Screenshot 2023-05-31 at 10 12 47

Also tried both in Editor and WebGL build, both working.

Screenshot 2023-05-31 at 10 19 47

Do you have them same exception in the editor too? You can replace the wallet connection with this line for a quick check: accountCurrent = await web3object.CreateAccount("your private key", "testpsw");, you can create a test wallet for testing.

GabrielePicco commented 1 year ago

Closing as stale, feel free to re-open if you are still experiencing the issue