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

Errors when calling Nft.TryGetNftData() method #94

Closed BlackDemonZyT closed 1 year ago

BlackDemonZyT commented 1 year ago

I log in with the wallet, the tokens get correctly with GetTokenAccounts(), but when i try to:

Solana.Unity.SDK.Nft.Nft.TryGetNftData() it fails.

Unity version: 2021.3.11f1

public async UniTask GetNftFromWallet()
{
    WalletBase wallet = new SolanaWalletAdapterWebGL(options, RpcCluster.MainNet, "https://api.metaplex.solana.com/", null, true);
    await wallet.Login();

    // Get Tokens of wallet
    Solana.Unity.Rpc.Models.TokenAccount[] tokens = await wallet.GetTokenAccounts(Commitment.Confirmed);

    // Sort tokens in descending 
    var tokenAccounts = tokens.OrderByDescending(tk => tk.Account.Data.Parsed.Info.TokenAmount.AmountUlong);

    foreach (var item in tokenAccounts)
    {
        Solana.Unity.SDK.Nft.Nft.TryGetNftData(item.Account.Data.Parsed.Info.Mint, Web3.Instance.Wallet.ActiveRpcClient).AsUniTask().ContinueWith(nftData =>
        {

        }).Forget();
    }
}

The errors are:

Not implemented: Class::FromIl2CppType

MethodAccessException: Attempt to access method 'Solana.Unity.Rpc.IRpcClient.GetAccountInfoAsync' on type '' failed.
Rethrow as AggregateException: One or more errors occurred. (Attempt to access method 'Solana.Unity.Rpc.IRpcClient.GetAccountInfoAsync' on type '' failed.)
  at System.Threading.Tasks.Task.ThrowIfExceptional (System.Boolean includeTaskCanceledExceptions) [0x00000] in <00000000000000000000000000000000>:0 
--- End of stack trace from previous location where exception was thrown ---

My gues is the error is from Packages/Solana Sdk/Runtime/codebase/nft/CandyMachineV2.cs in this line of code:

        public async Task<AccountResultWrapper<CandyMachine>> GetCandyMachineAsync(string accountAddress, Commitment commitment = Commitment.Finalized)
        {
      ->  var res = await RpcClient.GetAccountInfoAsync(accountAddress, commitment);
            if (!res.WasSuccessful)
                return new AccountResultWrapper<CandyMachine>(res);
            var resultingAccount = CandyMachine.Deserialize(Convert.FromBase64String(res.Result.Value.Data[0]));
            return new AccountResultWrapper<CandyMachine>(res, resultingAccount);
        }

But i do not know.

GabrielePicco commented 1 year ago

You are mixing the use of WalletBase and Web3. Web3 is a wrapper that internally have an instance of WalletBase, so either you define your own managing logic, or you attach Web3.cs to a gameObject and use the login function on it (e.g.: LoginWalletAdapter). I suggest the second option.

Otherwise, your code could be:

async void GetNftFromWallet()
    {
        var options = new SolanaWalletAdapterWebGLOptions();
        WalletBase wallet = new SolanaWalletAdapterWebGL(options, RpcCluster.MainNet, "https://api.metaplex.solana.com/", null, true);
        await wallet.Login();

        // Get Tokens of wallet
        var tokens = await wallet.GetTokenAccounts(Commitment.Confirmed);

        // Sort tokens in descending 
        var tokenAccounts = tokens.OrderByDescending(tk => tk.Account.Data.Parsed.Info.TokenAmount.AmountUlong);

        foreach (var item in tokenAccounts)
        {
            Nft.TryGetNftData(item.Account.Data.Parsed.Info.Mint, wallet.ActiveRpcClient).AsUniTask().ContinueWith(nftData =>
            {
                Debug.Log(nftData);
            }).Forget();
        }
    }