Exception occurs when using getSupportedCoins in Platform SDK

Hello. I’ve been playing around with the SBP SDK with the ultimate goal of making payment using STORJ tokens. So currently, I’m running the following code

mSblockchain = new SBlockchain();
mSblockchain.initialize(this);

HardwareWalletManager hardwareWalletManager = 
mSblockchain.getHardwareWalletManager();

Toast.makeText(this,"Got Instance",Toast.LENGTH_LONG).show();

List supportedCoinTypes = hardwareWalletManager.getConnectedHardwareWallet().getSupportedCoins(); 

but it is giving the following exception

Probably. I’m not able to retrieve the Connected Hardware wallet. Kindly enlighten me on this.

Also, how can I perform transactions using STORJ tokens through the SBP SDK code?

Hi,

You only get connected hardware wallet after you connect your hardware wallet with your application. So you have to connect hardware wallet first. Follow the programming guide to connect your application with your hardware wallet.

Hardware wallet connection is an asynchronous call. Inside onSuccess use code related to getSupportedCoins();

You can use like this.

@Override
public void onSuccess(HardwareWallet hardwareWallet) {
List supportedCoinTypes = hardwareWalletManager.getConnectedHardwareWallet().getSupportedCoins();
}

Thankyou, @M_A_Hasan_Molla.
I’m able to retrieve the supported coins but now I’m facing issues with the account management section wherein I’m getting an empty list of accounts. I even tried generating the account before getAccounts but it still won’t work.

Also, please consider the request for STORJ token transaction in the original request.

Hi,

I will suggest you to connect every action with a button. That will be helpful for you to test all APIs. Because every ListenableFutureTask needs some significant time as they are asynchronous tasks. Moreover, they need to be executed after finishing the dependent task as you see before.

Now the steps for STORJ token transaction is bellow:

  1. Create an instance of SBlockchain.
  2. Connect to Hardware Wallet.
  3. Create Account (It takes a significant amount of time so you can see Logcat in android studio for detecting network operation)
  4. Use addTokenAddress to add token with your Ethereum account.
  5. Now use sendTokenTransaction to send a token.

You can find help from here.

Sharing log will be helpful to detect your issue.

Thank you for the reply, @M_A_Hasan_Molla.

I am trying to follow what you said. But I’m still facing issues with the account creation. I tried generating and restoring account methods each but still unable to get an account.
Also, when I use the generateNewAccount method, I’m getting the following exception.

And following is the exception when I generateNewAccount after the restoreAccounts method(I’m not sure if I should really be doing this):

Please refer the following code:
package com.example.sdkpayment;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.samsung.android.sdk.blockchain.SBlockchain;
import com.samsung.android.sdk.blockchain.account.Account;
import com.samsung.android.sdk.blockchain.account.AccountManager;
import com.samsung.android.sdk.blockchain.coinservice.CoinNetworkInfo;
import com.samsung.android.sdk.blockchain.coinservice.CoinServiceFactory;
import com.samsung.android.sdk.blockchain.coinservice.ethereum.EthereumService;
import com.samsung.android.sdk.blockchain.exception.AccountException;
import com.samsung.android.sdk.blockchain.exception.HardwareWalletException;
import com.samsung.android.sdk.blockchain.exception.RemoteClientException;
import com.samsung.android.sdk.blockchain.exception.RootSeedChangedException;
import com.samsung.android.sdk.blockchain.network.EthereumNetworkType;
import com.samsung.android.sdk.blockchain.wallet.HardwareWallet;
import com.samsung.android.sdk.blockchain.wallet.HardwareWalletManager;
import com.samsung.android.sdk.blockchain.wallet.HardwareWalletType;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;

import com.samsung.android.sdk.blockchain.*;

import org.jetbrains.annotations.NotNull;

public class MainActivity extends AppCompatActivity {
TextView txt,txt2;
Button b1,b2,b3,b4;
Context context;
SBlockchain mSblockchain;
StringBuilder sb;
HardwareWalletManager hardwareWalletManager;
ArrayList suportedWallets;
ListenableFutureTask connectionTask;
HardwareWallet connectedHardwareWallet;
String supportedCoins;
CoinNetworkInfo coinNetworkInfo;
AccountManager accountManager;
ArrayList restoreTargets;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    txt = findViewById(R.id.textView);
    b1 = findViewById(R.id.button1);
    b2 = findViewById(R.id.button2);
    b3 = findViewById(R.id.button3);
    b4 = findViewById(R.id.button4);
    context = this;
    txt2 = findViewById(R.id.textView2);

    try {

        mSblockchain = new SBlockchain();
        mSblockchain.initialize(getApplicationContext());
        hardwareWalletManager = mSblockchain.getHardwareWalletManager();
        suportedWallets = mSblockchain.getSupportedHardwareWallet();


        coinNetworkInfo = new CoinNetworkInfo(
                CoinType.ETH,
                EthereumNetworkType.MAINNET,
                "https://mainnet.infura.io/v3/2e75dc3e014e412c97288f0b2169c5e0");
        txt.setText(coinNetworkInfo.toString());

        accountManager = mSblockchain.getAccountManager();


        EthereumService etherService =
                (EthereumService) CoinServiceFactory
                        .getCoinService(
                                context,
                                coinNetworkInfo
                        );
        //txt.setText(etherService.toString());


        //Toast.makeText(this,"Done",Toast.LENGTH_LONG).show();


        b1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                connectionTask = hardwareWalletManager.connect(suportedWallets.get(0), true);
                connectionTask.setCallback(
                        new ListenableFutureTask.Callback<HardwareWallet>() {
                            @Override
                            public void onSuccess(HardwareWallet hardwareWallet) {
                                //txt.setText(hardwareWallet.getVersion());
                                //if(hWallet.isConnected())
                                //txt.setText("Success");
                                //   accountManager = mSblockchain.getAccountManager();

                                //   List<Account> accountsList = accountManager.getAccounts(null,null,null);

                                //   txt.setText(accountsList.toString());
                                connectedHardwareWallet = hardwareWalletManager.getConnectedHardwareWallet();
                                //    if(connectedHardwareWallet!=null)
                                //       txt.setText("Ok till here");
                                //  else
                                //    txt.setText("empty");
                                txt2.setText("Done first");
                            }

                            @Override
                            public void onFailure(@NotNull ExecutionException e) {
                                Throwable cause = e.getCause();

                                if (cause instanceof HardwareWalletException) {
                                    // handling hardware wallet error
                                    //txt.setText("Hardware Exception");
                                } else if (cause instanceof RootSeedChangedException) {
                                    // handling root seed changed exception
                                    //txt.setText("Root seed changed");
                                }
                            }

                            @Override
                            public void onCancelled(@NotNull InterruptedException e) {
                                //txt.setText("cancelled");
                            }
                        });

            }
        });

        b2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            /*    List<Account> accountsList = accountManager.getAccounts(connectedHardwareWallet.getWalletId(),
                        CoinType.ETH,
                        EthereumNetworkType.MAINNET);
                txt.setText(accountsList.toString());
             */
                ListenableFutureTask.Callback<Account> generatingNewAccountCallback =
                        new ListenableFutureTask.Callback<Account>() {
                            @Override
                            public void onSuccess(Account account) {
                                //Log.i(TAG, "Generated account address: " + account.getAddress());
                                //txt.setText(account.getAddress());
                             /*   List<Account> accountsList = accountManager.getAccounts(connectedHardwareWallet.getWalletId(),
                                        CoinType.ETH,
                                        EthereumNetworkType.MAINNET);
                              */
                                //txt.setText(accountsList.toString());
                                txt2.setText(account.toString());
                            }

                            @Override
                            public void onFailure(@NotNull ExecutionException e) {
                                Throwable cause = e.getCause();

                                if (cause instanceof AccountException) {
                                    // handling account error
                                    txt.setText("Account Exception");
                                } else if (cause instanceof RootSeedChangedException) {
                                    // handling root seed changed exception
                                    txt.setText("Root Seed Changed");
                                } else if (cause instanceof RemoteClientException) {
                                    txt.setText("Remote Client Exception");
                                    // handling network error
                                } else{
                                    txt2.setText(e.toString());
                                }
                            }

                            @Override
                            public void onCancelled(@NotNull InterruptedException e) {
                                txt.setText("On cancelled");
                            }
                        };


                generateNewAccount()
                        .setCallback(generatingNewAccountCallback);
            }
        });

        b3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                restoreTargets = new ArrayList<>();
                restoreTargets.add(coinNetworkInfo);

                ListenableFutureTask.Callback<List<CoinNetworkInfo>> restoreAccountsCallback =
                        new ListenableFutureTask.Callback<List<CoinNetworkInfo>>() {
                            @Override
                            public void onSuccess(List<CoinNetworkInfo> result) {
                                txt2.setText(result.toString());
                            }

                            @Override
                            public void onFailure(@NonNull final ExecutionException e) {
                                Throwable cause = e.getCause();

                                if (cause instanceof AccountException) {
                                    // handling account error
                                    txt2.setText("A Exception");
                                } else if (cause instanceof RootSeedChangedException) {
                                    // handling root seed changed exception
                                    txt2.setText("Root Seed ");
                                } else if (cause instanceof RemoteClientException) {
                                    // handling network error
                                    txt2.setText("RC exception");
                                }
                                else{
                                    txt2.setText("Exception unkown");
                                }

                            }

                            @Override
                            public void onCancelled(@NotNull InterruptedException exception) {

                            }
                        };
                accountManager.restoreAccounts(
                        connectedHardwareWallet,
                        true,
                        restoreTargets)
                        .setCallback(restoreAccountsCallback);

            }
        });

        b4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                txt.setText(restoreTargets.toString());
                boolean result = CoinServiceFactory.getCoinService(getApplicationContext(),coinNetworkInfo).isValidAddress("0xd9fff827c1fef8dc660c0a24f9f477c320434fdf");
                txt2.setText(String.valueOf(result));
            }
        });

 /*       if(connectedHardwareWallet!=null)
            Toast.makeText(this,"Done",Toast.LENGTH_LONG).show();
        else
            Toast.makeText(this,"Failed",Toast.LENGTH_LONG).show();
   */
        //txt.setText(hWallet.toString());
        //txt.setText(suportedWallets.toString());


    } catch (Exception e) {
        // handling exception
            txt.setText(e.getMessage());
            Toast.makeText(this,"Failed",Toast.LENGTH_LONG).show();
    }


    }

public ListenableFutureTask<Account> generateNewAccount(){
    return accountManager.generateNewAccount(connectedHardwareWallet,coinNetworkInfo);
}

}

Hi,

First, add all dependencies in the app Gradle. Follow the instruction provided here.

Now in

accountManager.generateNewAccount(connectedHardwareWallet,coinNetworkInfo)

You have provided connectedHardwareWallet which is null. Because when you connect the hardware wallet, OnSucess call back gives you a HardwareWallet type object.

public void onSuccess(HardwareWallet hardwareWallet)

You have to save this hardwareWallet to connectedHardwareWallet inside OnSucess call back.

Instead of this-

connectedHardwareWallet = hardwareWalletManager.getConnectedHardwareWallet();

Simply save the object that you get from the call back as a result. Use this-

connectedHardwareWallet = hardwareWallet

I hope this will solve your issue.

Thank you.

All the dependencies were already added in my gradle file.
I tried saving the “hardwareWallet” the way you suggested, but the issue persists!

Perhaps providing the whole log could be helpful to understand the problem.

I’m afraid I won’t be able to provide the log because I’m testing the app by building the apk since I don’t have physical access to the device I’m testing on.

Hi @M_A_Hasan_Molla,
Please find the attached apk link with and kindly try running it with reference to the above shared code.

Hi,

I am not sure what you meant by that. Do you have the whole project source code? Or you are only testing the project by creating apk?
If you have the whole project code and you can run it in android studio please give the log that shows in the following picture.

Could you please also attach your gradle file??

Hello,
As I mentioned above, I don’t have a physical access to a SDK supporting device nor am I able to run a corresponding emulator due to unsupported port 2600 in India. So, I do not get the log file that you mentioned. Perhaps, I’m testing my code on a remote device in US by running the APK(whose link I shared earlier).
Indeed, you could test the code. I can share the complete project containing the gradle and xml files both, if you say.

Hi,

Please share the project like before.

Hi,
I tried uploading the project but uploading gets unsuccessful due to large size probably.
Would it be appropriate for me to share the project on another platform? If yes, kindly share the platform details.

Please share your app Gradle file. May be there is a problem with it. So as you are facing problem with uploading the whole project please share the gradle first.

OK sure.
Please find the gradle file attached.
build.gradle.zip (1.2 KB)

Hi,
Use this in your Gradle file. I hope this will solve your problem.

android{

compileOptions {
    sourceCompatibility = '1.8'
    targetCompatibility = '1.8'
}

}

Hi,
That didn’t work either!

Hi,
You can use any popular sharing site and provide us the shared link. I think this way you can share the project.

Okay. I’ll try that.