API Implementation

Samsung Blockchain Keystore API Level

Samsung Blockchain Keystore API Level plays a key role to ensure that the required API level of Samsung Blockchain Keystore on a user’s device is properly installed to support the API that your Android app tries to call.

For example, if your Android app is trying to implement a new Samsung Blockchain Keystore API that requires “API Level 2”, your Android app will need to check whether Samsung Blockchain Keystore app installed on user’s device also supports API Level 2. If a user’s app supports API Level 1, then your app will need to guide users to update Samsung Blockchain Keystore app to the latest version. Users can be directed to the update page in Galaxy Store. Otherwise, there will be a runtime exception due to API Level Exception when calling APIs with level higher than the level supported by the user’s version.

The API Level for each API will be mentioned in the Javadoc, under “Since” title, and developers can call “getKeystoreApiLevel API” to check the current API Level on the user’s device. Your Android app will need to check the API Level whenever needed – it may be at the beginning of running Samsung Blockchain Keystore app or every time your app calls an API.

    public void getKeystoreApiLevel() {
        int keystoreApiLevel = ScwService.getInstance().getKeystoreApiLevel();
        boolean isKeystoreApiSupported = keystoreApiLevel > 0;
    }

Get Instance

ScwService.getInstance( ) will need to be used to call any of the APIs provided by Samsung Blockchain Keystore. If Samsung Blockchain Keystore is supported on the device, an instance will be returned. If it is not available on the device, then null will be returned. If null is returned, it means Samsung Blockchain Keystore is not supported on the user’s device. A different keystore or a wallet needs to be used.

    ScwService scwServiceInstance = ScwService.getInstance();
            

Get Seed Hash

getSeedHash API aims to help developers distinguish two things:

(1) Check whether user has set up Samsung Blockchain Keystore.

(2) Check whether Master Seed (recovery phrase) has been changed or not.

Every time a new Master Seed (or a wallet) is created or restored, pseudo Seed Hash in a String value will be randomly generated. This will not be related to the contents of the Master Seed.

If the length of the seedHash is zero (not null), it means Samsung Blockchain Keystore has not been initialized yet. Developers will need to guide users to jump to Samsung Blockchain Keystore to create or restore a wallet to utilize Samsung Blockchain Keystore features by implementing a deeplink, ScwDeepLink.MAIN.

If the returned seedHash value is same as previously cached seedHash value by your Android app, it means there was no change to the Master Seed, so the previously derived address that was linked to your Android app is still valid and matches the correct Master Seed. Hence, the developers will not need to call getAddressList API again.

However, if the Master Seed has been changed due to user resetting and re-creating a wallet, then a different Seed Hash value will be returned and your app will need to get the address that corresponds to the HD path. Having a different Master Seed implies that the public key and the address corresponding to a specified HD path has also been changed.

    public void getSeedHash() {
        String seedHash = ScwService.getInstance().getSeedHash();
        boolean initialized =  (seedHash != null && seedHash.length() > 0);
    }

Check Mandatory App Update

checkForMandatoryAppUpdate API is used by to check if a user must update Samsung Blockchain Keystore. Because Samsung Blockchain Keystore handles only one task at a time, make sure to NOT call checkForMandatoryAppUpdate API in the background as it may cause other API calls or requests to be cancelled.

If a mandatory app update is needed, users can be directed to the Galaxy Store using a deeplink, ScwDeepLink.GALAXY_STORE. Otherwise, users will see the mandatory app update popups during an operation process, such as signing a transaction, and will need to update Samsung Blockchain Keystore before proceeding.

Note: ScwService.ScwCheckForMandatoryAppUpdateCallback will need to be implemented correspondingly .

    ScwService.ScwCheckForMandatoryAppUpdateCallback callback =
            new ScwService.ScwCheckForMandatoryAppUpdateCallback() {
                           @Override
                           public void onMandatoryAppUpdateNeeded(boolean needed) {
                               if(needed){
                                   startDeepLink(ScwDeepLink.GALAXY_STORE);
                               }
                           }
                       };
           
    ScwService.getInstance().checkForMandatoryAppUpdate(callback);
  • How to handle the returned value

    A Boolean needed value of whether a mandatory update is needed or not will be returned.

    If needed, developers will need to guide users to go to Samsung Blockchain Keystore app page in Galaxy Store to update.

Get Supported Coins

getSupportedCoins API is used to find out which type of cryptocurrencies are supported, in case there is a different logic that developers must implement for different cryptocurrencies. It is returned in an int array of standard coin types according to BIP standard – for example, 60 for Ethereum.

    int[] supportedCoins = ScwService.getInstance().getSupportedCoins();
        
            StringBuilder sb = new StringBuilder();
            sb.append("Supported coins").append('\n');
            for (int i = 0; i < supportedCoins.length; i++ ) {
                sb.append('[').append(i).append("] ").append(supportedCoins[i]).append('\n');
            }
    
            String s = sb.toString();

Get a list of Addresses

getAddressList API allows developers to request to get a list of addresses that correspond to a list of HD Paths. A list of the HD Path, compatible with BIP-44 needs to be passed on to bring the addresses. The depth of HD path should be between 3 and 6.

Also, ScwService.ScwGetAddressListCallback will need to be implemented correspondingly.

    ScwService.ScwGetAddressListCallback callback = 
            new ScwService.ScwGetAddressListCallback() {
                            @Override
                            public void onSuccess(List<String> addressList) {
                                
                            }
            
                            @Override
                            public void onFailure(int errorCode) {
                                //handle errors
            
                            }
                        };
            
            
                    String hdpath1 = "m/44'/60'";
                    String hdpath2 = "m/44'/60'/0'";
                    String hdpath3 = "m/44'/60'/0'/0";
            
                    ArrayList<String> hdPathList = new ArrayList<>();
                    hdPathList.add(hdpath1);
                    hdPathList.add(hdpath2);
                    hdPathList.add(hdpath3);
            
    ScwService.getInstance().getAddressList(callback, hdPathList);
            
  • Hierarchical Deterministic Path (HD Path) Examples

    hdPath = m/44'/60'/0'/0/0

  • How to handle the returned value

    The returned value will be a list of addresses in a List<String> format. Each address will correspond to the HD path in the ArrayList<String>.

  • Minimize calling getAddressList API by checking Seed Hash value

    To avoid calling getAddressList API as much as possible, please utilize getSeedHash API to check whether the Master Seed has been changed or not, since different Seed Hash value implies that the corresponding address has also been updated.

Get a list of Extended Public Keys

getExtendedPublicKeyList API allows developers to request to get a list of extended Public Keys that correspond to a list of HD Paths. A list of the HD Path, compatible with BIP-44 needs to be passed on to bring the public key. The depth of path should be between 3 and 6.

Also, note that ScwService.ScwGetExtendedPublicKeyListCallback will need to be implemented correspondingly.

    ScwService.ScwGetExtendedPublicKeyListCallback callback = 
            new ScwService.ScwGetExtendedPublicKeyListCallback() {
                            @Override
                            public void onSuccess(List<byte[]> extendedPublicKeyList) {
                                
                            }
            
                            @Override
                            public void onFailure(int errorCode) {
                                //handle errors
            
                            }
                        };
            
            
                    String hdpath1 = "m/44'/60'";
                    String hdpath2 = "m/44'/60'/0'";
                    String hdpath3 = "m/44'/60'/0'/0";
            
                    ArrayList<String> hdPathList = new ArrayList<>();
                    hdPathList.add(hdpath1);
                    hdPathList.add(hdpath2);
                    hdPathList.add(hdpath3);
            
    ScwService.getInstance().getExtendedPublicKeyList(callback, hdPathList);
  • Hierarchical Deterministic Path (HD Path) Examples

    hdPath = m/44'/60'/0'/0/0

  • How to handle the returned value

    The returned value will be List<byte[]> that corresponds to each HD path requested in the ArrayList<String>. Each byte array is composed of 33 bytes of compressed public key and 32 bytes of chain code. You can derive the child public key based on this data. Also note that you need to derive the address of the compressed public key or call getAddressList API to get the address.

  • Minimize calling getExtendedPublicKeyList API by checking Seed Hash value

    Use getSeedHash API to check whether the Master Seed has been changed or not, since different Seed Hash value implies that corresponding public keys have also been updated.

Sign a Transaction

There are currently four APIs that support signing cryptocurrency transactions; Ethereum, Personal Sign Message in Ethereum, Bitcoin and Klaytn.

Note: Only signing a transaction is included in the Samsung Blockchain Keystore scope.

  1. 1)

    signEthTransaction API as the name implies, sends a request to Samsung Blockchain Keystore to sign an Ethereum Transaction. Likewise, ScwService.ScwSignEthTransactionCallback will need to be implemented.

        ScwService.ScwSignEthTransactionCallback callback = 
                new ScwService.ScwSignEthTransactionCallback() {
                                @Override
                                public void onSuccess(byte[] signedEthTransaction) {
                                    
                                }
                
                                @Override
                                public void onFailure(int errorCode) {
                                    //handle error
                                    
                                }
                            };
                
                
                            String toAddress = "0xe7425ee1bc64ab7c51ce3617cb83e76fd545f1a9";
                            String ethAmount = "123.456789";
                            String ethGasPrice = "12000000000";
                            String ethGasLimit = "21000";
                            String data = "";
                
                String hdPath = "m/44'/60'/0'/0/0";
                
                byte[] encodedUnsignedEthTx = createRawTransaction(toAddress, ethAmount, ethGasPrice, ethGasLimit, data);
                
                private byte[] createRawTransaction(param1, param2, …){
                
                      //Implement your code here
                
                }
                
        ScwService.getInstance().signEthTransaction(callback, encodedUnsignedEthTx, hdPath);
                

    The parameters to take note of are as follows:

    • encodedUnsignedEthTx : a byte array of a RLP-encoded unsigned Ethereum raw transaction.

    • hdPath : HD Path that corresponds to the address linked to your Android app that also corresponds to the private key that will be used for signing

    • ERC20 Tokens and Smart Contract

      For ERC20 tokens, your Android app can use this “signEthTransaction API”, but will need to make sure to encode the token’s smart contract address, token amount, and recipient address in the correct format when generating a byte[ ] encodedUnsignedEthTx.

      1. (1) For ERC20 tokens supported by Samsung Blockchain Keystore, the smart contract address, recipient address, token name, token symbol, and token amount will be parsed and shown to the user when user confirms the transaction, along with other Ethereum transaction data, such as gas fee, gas limit, and maximum gas price.

      2. (2) For unknown tokens, or tokens not supported by Samsung Blockchain Keystore, the smart contract address, recipient address and token amount will be shown upon user’s confirmation to sign the transaction, along with other Ethereum transaction data, such as gas fee, gas limit, and maximum gas price. Unlike ERC20 tokens supported by Samsung Blockchain Keystore, neither the token name nor token symbol will be parsed or shown to users.

    • How to handle the returned value

      The signed transaction will be returned in a byte array type in a RLP-encoded format.

  2. 2)

    signEthPersonalMessage API can be used to request to Samsung Blockchain Keystore to sign a message in Ethereum. ScwService.ScwSignEthPersonalMessageCallback will need to be implemented.

        ScwService.ScwSignEthPersonalMessageCallback callback = 
            new ScwService.ScwSignEthPersonalMessageCallback() {
                            @Override
                            public void onSuccess(byte[] signedPersonalMessage) {
                                
                            }
            
                            @Override
                            public void onFailure(int errorCode) {
                                //handle error
                                
                            }
                        };
            
            
            String hdPath = "m/44'/60'/0'/0/0";
               byte[] unSignedMsg = "To sign up, please sign this message.".getBytes();
            
               ScwService.getInstance().signEthPersonalMessage(callback, unSignedMsg, hdPath);

    The parameters to take note of are as follows:

    • unSignedMsg – a byte array of raw message to be signed by Samsung Blockchain Keystore. The "\u0019Ethereum Signed Message:\n" prefix will be added by Samsung Blockchain Keystore, so your Android app should not include the prefix in the message.

    • hdpath : HD Path that corresponds to the address linked to your Android app that also corresponds to the private key that will be used for signing

    • How to handle the returned value:

      The type of return is a byte array of signed message based on R, S, V (values for a transaction’s signature) respectively.

  3. 3)

    signBtcTransaction API can be used to create a request to Samsung Blockchain Keystore to sign a Bitcoin transaction. ScwService.ScwSignBtcTransactionCallback will need to be implemented.

    ScwService.ScwSignBtcTransactionCallback callback = 
            new ScwService.ScwSignBtcTransactionCallback() {
                            @Override
                            public void onSuccess(byte[] signedBtcTransaction) {
                                
                            }
            
                            @Override
                            public void onFailure(int errorCode) {
                                //handle error
                                
                            }
                        };
            
            
            ArrayList<String >  inputHdPathList = new ArrayList<>();
            String changeHdPath = "m/44'/0'/0'/0/0";
            String inputHdPath = "m/44'/0'/0'/0/0";
            
            
            Transaction unsignedtx = getUnsignedTransaction(networkParams, utxos, to, value, fee);
            
            ArrayList<byte[]> utxoTransactionsList = new ArrayList<>();
            for (int i = 0; i < unsignedTx.getInputs().size(); i++) {
                inputHdPathList.add(inputHdPath);
                     TransactionInput input = unsignedTx.getInputs().get(i);
                     String txid = input.getOutpoint().getHash().toString();
            
                     if (utxoTransactions.containsKey(txid + input.getOutpoint().getIndex())) {
                             byte[] txRaw = utxoTransactions.get(txid + input.getOutpoint().getIndex());
                            Transaction transaction = new Transaction(networkParams, txRaw);
                             utxoTransactionsList.add(txRaw);
                      }
                 }
            
            private Transaction getUnsignedTransaction ( NetworkParameters networkParams, List<UTXO> utxos,
             String to, long value, long fee){
                  //Implement your code here
            
            }
            
            
                ScwService.getInstance().signBtcTransaction(callback, transaction, inputHdPathList, utxoTransactionsList, changeHdPath);

    The parameters to take note of are as follows:

    • transaction a byte array of a serialized unsigned Bitcoin transaction to be signed by Samsung Blockchain Keystore.

    • inputHdPathList : a list of HD Path that corresponds to the addresses linked to utxoTransactionsList, a component to create a transaction. This list also corresponds to the private key that will be used for signing. BIP-44, 49, 84 are supported and coin type “1” in HD Path can be used for Bitcoin test network.

    • utxoTransactionsList: a list of byte array of the serialized transactions that contain the UTXO used in this transaction

    • changeHdPath : the HD path that corresponds to the change address

    • How to handle the returned value:

      The signed transaction will be returned in a byte array type.

  4. 4)

    signKlayTransaction API can be used to request to Samsung Blockchain Keystore to sign a Klaytn transaction. ScwService.ScwSignKlayTransactionCallback will need to be implemented.

    ScwService.ScwSignKlayTransactionCallback callback = 
            new ScwService.ScwSignKlayTransactionCallback() {
                            @Override
                            public void onSuccess(byte[] signedKlayTransaction) {
                                
                            }
            
                            @Override
                            public void onFailure(int errorCode) {
                                //handle error
                                
                            }
                        };
            
            String hdPath = "m/44'/60'/0'/0/0";
                        byte[] unSignedTransaction = getUnsignedTx();
                        int klaytnChainId = 1001;
            
            
                ScwService.getInstance().signKlayTransaction(callback,  unSignedTransaction, hdPath, klaytnChainId);
            

    The parameters to take note of are as follows:

    • unSignedTransaction a byte array of raw transaction to be signed by Samsung Blockchain Keystore. It is same as the sigRLP value mentioned in Klaytn official document.

    • hdPath - HD Path that corresponds to the public key linked to the partner’s wallet that also corresponds to the private key that will be used for signing.

    • klaytnChainId – The Klaytn network ID or the integer to identify the network.
      "8217" is Klaytn Cypress Mainnet and "1001" is Klaytn Baobab Testnet.

    • How to handle the returned value:

      The signed transaction will be returned in a byte array type in a RLP-encoded format.

Go to Samsung Blockchain Keystore Settings

Samsung Blockchain Keystore provides a user-friendly setup page for the first time users and a Settings page for existing users. Developers can easily jump to Samsung Blockchain Keystore Settings by using a deeplink, ScwDeepLink.MAIN.. There are two purposes of calling the Samsung Blockchain Keystore Main activity.

 
  1. 1)

    Setup Samsung Blockchain Keystore for first time users

    After calling getSeedHash API, if the wallet is not created, a zero length value will be returned. This is when your Android app should call Samsung Blockchain Keystore Settings via a deep link as shown below. Samsung Blockchain Keystore will check if a user needs to set up a new wallet and if needed, will lead to a setup page. After the activity is finished, your Android app should call the getSeedHash API, once more, to make sure that the wallet has been created and the corresponding Seed Hash value is returned.

  2. 2)

    Samsung Blockchain Keystore Settings for existing users

    For existing users, when Samsung Blockchain Keystore Settings is called, a user will see a list of menu related to Samsung Blockchain Keystore management. Features include changing the PIN, removing the wallet, checking a recovery phrase to back up the wallet, enabling/disabling Fingerprint as an authentication method, or changing alarm notifications settings. More information about the Samsung Blockchain Keystore, such as Notices, Terms and Conditions, and App Information can be also found here.

A sample code for calling Samsung Blockchain Keystore via a deeplink is as follows.

Uri uri = Uri.parse(ScwDeepLink.MAIN);
Intent displayIntent = new Intent(Intent.ACTION_VIEW, uri);
displayIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent); 

*Do NOT call startActivityForResult(intent) as no results will be returned. Make sure to use startActivity(intent) instead.

Handling Error Codes

In addition to general error codes, the following are some special cases that developers may want to look out for.

  • Mandatory Update is needed

  • Samsung Blockchain Keystore was removed due to user entering wrong PIN more than N times

  • App ID is invalid

The popups above will be shown from Samsung Blockchain Keystore app, though the Samsung Blockchain Keystore will still return corresponding error codes. In the Mandatory Update error case, the user will see a popup with a link to Galaxy Apps Store page to update Samsung Blockchain Keystore. If it was reset, due to entering a wrong PIN more than N times, then the user will need to create or import the wallet via Samsung Blockchain Keystore service again.

It is recommended that developers call checkForMandatoryAppUpdate API before calling other APIs, to check whether a mandatory app update is needed. For this API, no UI or popup will be shown from Samsung Blockchain Keystore.

Upon integration, developers may receive an “ERROR_INVALID_SCW_APP_ID” error. In this case, developers can turn on Developer Mode to skip the app verification stage. Yet, developers will need to implement proper App ID, officially issued by the Samsung Blockchain Keystore team before launching your Android app in the market.

public interface ScwErrorCode {
    int ERROR_MANDATORY_APP_UPDATE_NEEDED = -8;
    int ERROR_INVALID_SCW_APP_ID = -11;
    int ERROR_WALLET_RESET = -12;
    int ERROR_CHECK_APP_VERSION_FAILED = -15;
    int ERROR_TNC_NOT_AGREED = -6;
}

Please refer to the ScwErrorCode class in JavaDoc for more details on error codes.

Deeplinks to Samsung Blockchain Keystore features changing PIN, viewing Recovery Phrase, resetting Wallet, and updating in Galaxy Store. Developers can implement the links below to direct users to go to a specific menu in Samsung Blockchain Keystore Settings directly. The following is a list of Samsung Blockchain Keystore deeplinks to help developers utilize Samsung Blockchain Keystore service directly.

UV index values have 12 levels.
Features Deeplink
Main page ScwDeepLink.MAIN
Change PIN ScwDeepLink.CHANGE_PIN
Reset Wallet ScwDeepLink.RESET
Display Wallet (Recovery Phrase) ScwDeepLink.DISPLAY_WALLET
Notice contents ScwDeepLink.NOTICE_CONTENT
Galaxy Apps Store ScwDeepLink.GALAXY_STORE