Wallet SDK is a mobile application development SDK that enables developers to integrate the functionality of a non-custodial crypto-wallet into consumer applications. The SDK:
- Safely generates and stores keys on the user's mobile device
- Signs ethereum transactions and data as defined by contracts using EIP-1077
- Enables users to recover access to their Brand Tokens in case the user loses their authorized device
- Java Compile version: 1.7
- Android version support: 22 and above
Add the OST SDK as a dependency in build.gradle
dependencies {
implementation 'com.ost:ost-wallet-sdk-android:2.2.2'
}
A config file is needed for application-specific configuration of OST SDK.
- Create file "ost-mobilesdk.json" with application specific configurations using the json below as an example
{
"BLOCK_GENERATION_TIME": 3,
"PIN_MAX_RETRY_COUNT": 3,
"REQUEST_TIMEOUT_DURATION": 60,
"SESSION_BUFFER_TIME": 3600,
"PRICE_POINT_CURRENCY_SYMBOL": "USD",
"USE_SEED_PASSWORD": false
}
-
Place the file under main directory's assets folder
File path example: app -> src -> main -> assets -> ost-mobilesdk.json
NOTE:These configurations are MANDATORY for successful operation. Failing to set them will significantly impact usage.
Add compile options for Java 1.8 version in the Application's build.gradle
files
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
SDK initialization should happen before calling any other workflow. To initialize the SDK, we need to call init workflow of wallet SDK. It initializes all the required instances and run db migrations.
Recommended location to call init() is in Application sub-class.
Parameters
parameter context: ApplicationContext.
parameter baseUrl: OST Platform endpoint.
initialize(context, baseUrl)
public void onCreate() {
super.onCreate();
OstSdk.initialize(getApplicationContext(), BASE_URL);
}
This workflow needs userId
and tokenId
so setupDevice may be called after the user logs in to the application. Using a mapping between userId in OST Platform and the app user, you have access to userId and tokenId.
If the user is logged in, then setupDevice should be called every time the app launches, this ensures that the current device is registered before communicating with OST Platform server.
Parameters
parameter userId: Ost User id
parameter tokenId: Id assigned by Ost to token
parameter workFlowCallback: callback implementation object for application communication
void setupDevice(String userId, String tokenId, OstWorkFlowCallback workFlowCallback)
OstSdk.setupDevice(userId, tokenId, new OstWorkFlowCallbackImpl());
User activation refers to the deployment of smart-contracts that form the user's Brand Token wallet. An activated user can engage with a Brand Token economy.
Parameters
parameter UserPassphrase: object which will contain user Id, user pin and passphrasePrefix
parameter expiresAfterInSecs: session key expiry time
parameter spendingLimit: spending limit once in a transaction of session
parameter workFlowCallback: callback implementation object for application communication
void activateUser(UserPassphrase passphrase, long expiresAfterInSecs, String spendingLimit, OstWorkFlowCallback callback)
UserPassphrase userPassPhrase = new UserPassphrase(userId, pin, passphrasePrefix)
OstSdk.activateUser(userPassPhrase, expiresAfterInSecs, spendingLimit, new OstWorkFlowCallbackImpl())
A session is a period of time during which a sessionKey
is authorized to sign transactions under a pre-set limit on behalf of the user.
The device manager, which controls the tokens, authorizes sessions.
Parameters
parameter userId: Ost User id
parameter expiresAfterInSecs: sessions key expiry time
parameter spendingLimit: spending limit once in a transaction of session
parameter workFlowCallback: callback implementation object for application communication
void addSession(String userId, long expireAfterInSecs, String spendingLimit, OstWorkFlowCallback workFlowCallback)
OstSdk.addSession(userId, expireAfterInSecs, spendingLimit, new OstWorkFlowCallbackImpl())
A transaction where Brand Tokens are transferred from a user to another actor within the Brand Token economy are signed using sessionKey
if there is an active session. In the absence of an active session, a new session is authorized.
Parameters
parameter userId: Ost User id
parameter tokenHolderAddresses: Token holder addresses of amount receiver
parameter amounts: Amounts corresponding to tokenHolderAddresses to be transfered
parameter ruleName: Rule name to be executed
parameter meta: meta data of transaction to be associated
Example:-
{"name": "transaction name",
"type": "user-to-user",
"details": "like"}
parameter options: Map containing options of transactions
Example:-
{"currency_code": "USD",
"wait_for_finalization": true}
parameter workFlowCallback: callback implementation object for application communication
void executeTransaction(String userId, String tokenId, List tokenHolderAddresses, List amounts, String ruleName, Map meta, Map options, OstWorkFlowCallback workFlowCallback)
OstSdk.executeTransaction(userId, tokenHolderAddresses, amounts, ruleName, meta, options, new OstWorkFlowCallbackImpl())
The mnemonic phrase represents a human-readable way to authorize a new device. This phrase is 12 words long.
Parameters
parameter userId: Ost User id
parameter workFlowCallback: callback implementation object for application communication
void getDeviceMnemonics(String userId, OstWorkFlowCallback workFlowCallback)
OstSdk.getDeviceMnemonics(String userId, new OstWorkFlowCallbackImpl())
A user that has stored their mnemonic phrase can enter it into an appropriate user interface on a new mobile device and authorize that device to be able to control their Brand Tokens.
Parameters
parameter userId: Ost User id
parameter mnemonics: byte array of paper wallet
parameter workFlowCallback: callback implementation object for application communication
void authorizeCurrentDeviceWithMnemonics(String userId, byte[] mnemonics, OstWorkFlowCallback ostWorkFlowCallback)
OstSdk.authorizeCurrentDeviceWithMnemonics(userId, mnemonics, new OstWorkFlowCallbackImpl())
A developer can use this method to generate a QR code that displays the information pertinent to the mobile device it is generated on. Scanning this QR code with an authorized mobile device will result in the new device being authorized.
Parameters
parameter userId: Ost User id
Bitmap getAddDeviceQRCode(String userId)
OstSdk.getAddDeviceQRCode(userId)
QR codes can be used to encode transaction data for authorizing devices, making purchases via webstores, etc.This method can be used to process the information scanned off a QR code and act on it.
Parameters
parameter userId: Ost User id
parameter data: JSON object string scanned from QR code
parameter workFlowCallback: callback implementation object for application communication
void performQRAction(String userId, String data, OstWorkFlowCallback workFlowCallback)
OstSdk.performQRAction(userId, data, new OstWorkFlowCallbackImpl())
The user's PIN is set when activating the user. This method supports re-setting a PIN and re-creating the recoveryOwner.
parameter userId: Ost User id
parameter appSalt: Salt provided by app
parameter currentPin: current pin to be change
parameter newPin: new pin to be updated
parameter workFlowCallback: callback implementation object for application communication
void resetPin(String userId, String appSalt, String currentPin, String newPin, OstWorkFlowCallback workFlowCallback)
OstSdk.resetPin(userId, appSalt, currentPin, newPin, new OstWorkFlowCallbackImpl())
A user can control their Brand Tokens using their authorized devices. If they lose their authorized device, they can recover access to their BrandTokens by authorizing a new device via the recovery process .
parameter userId user id of recovery user
parameter passphrase Struct of current passPhrase
parameter deviceAddressToRecover Address of device to recover
parameter workFlowCallback Work flow interact
void initiateDeviceRecovery(String userId, UserPassphrase passphrase, String deviceAddressToRecover, OstWorkFlowCallback workFlowCallback)
OstSdk.initiateDeviceRecovery(userId, passphrase, deviceAddressToRecover, new OstWorkFlowCallbackImpl())
To abort initiated device recovery.
parameter userId userId of recovery user
parameter passphrase A simple struct to transport pin information via app and Sdk.
parameter workFlowCallback Workflow callback Interact
void abortDeviceRecovery(String userId, UserPassphrase passphrase, OstWorkFlowCallback workFlowCallback)
OstSdk.abortDeviceRecovery(userId, passphrase, new OstWorkFlowCallbackImpl())
This method can be used to enable or disable the biometric.
parameter userId userId of user
parameter enable A flag to enable or disable user biometric preference.
parameter workFlowCallback Workflow callback Interact
void updateBiometricPreference(String userId, boolean enable, OstWorkFlowCallback workFlowCallback)
OstSdk.updateBiometricPreference(userId, enable, new OstWorkFlowCallbackImpl())
To revoke device access.
parameter userId userId of user
parameter deviceAddress Address of device to revoke
parameter workFlowCallback Workflow callback Interact
void revokeDevice(String userId, String deviceAddress , OstWorkFlowCallback workFlowCallback)
OstSdk.revokeDevice(userId, deviceAddress, new OstWorkFlowCallbackImpl())
It will revoke all the sessions associated with provided userId
parameter userId user Id whose sessions to revoke
parameter workFlowCallback Workflow callback interact
void logoutAllSessions(String userId, OstWorkFlowCallback workFlowCallback)
OstSdk.logoutAllSessions(userId, new OstWorkFlowCallbackImpl())
To get User Entity
parameter userId user Id whose entity to retrieve
OstUser getUser(String userId)
OstSdk.getUser(userId)
To get Token Entity
parameter tokenId token Id whose entity to retrieve
OstToken getToken(String tokenId)
OstSdk.getToken(tokenId)
To check whether biometric of provide userId is enabled for this device or not
parameter userId user Id whose biometric config to retrieve
boolean isBiometricEnabled(String userId)
OstSdk.isBiometricEnabled(userId)
Callbacks to be implemented by application before calling any of the above WorkFlows.
/**
* Register device passed as parameter
*
* @param apiParams Register Device API parameters
* @param ostDeviceRegisteredInterface To pass response
*/
void registerDevice(JSONObject apiParams, OstDeviceRegisteredInterface ostDeviceRegisteredInterface)
Argument | Description |
---|---|
apiParams JSONObject |
Device information for registration |
ostDeviceRegisteredInterface OstDeviceRegisteredInterface |
OstDeviceRegisteredInterface.deviceRegistered(JSONObject newDeviceEntity ) should be called to pass the newly created device entity back to SDK. In case data is not verified the current workflow should be canceled by developer by calling OstDeviceRegisteredInterface.cancelFlow() |
/**
* Ask SDK user to verify data to proceed
*
* @param ostWorkflowContext info about workflow type
* @param ostContextEntity info about entity
* @param ostVerifyDataInterface to acknowledge workflow to proceed
*/
void verifyData(OstWorkflowContext ostWorkflowContext, OstContextEntity ostContextEntity, OstVerifyDataInterface ostVerifyDataInterface)
Argument | Description |
---|---|
ostWorkflowContext OstWorkflowContext |
Information about the current workflow during which this callback will be called |
ostContextEntity OstContextEntity |
Information about the entity |
ostVerifyDataInterface OstVerifyDataInterface |
ostVerifyDataInterface.dataVerified() should be called if the data is verified successfully. In case data is not verified the current workflow should be canceled by developer by calling ostVerifyDataInterface.cancelFlow() |
/**
* Pin needed to check the authenticity of the user.
* Developers should show pin dialog on this callback
*
* @param ostWorkflowContext holds work flow type
* @param userId Id of user whose password and pin are needed.
* @param ostPinAcceptInterface To pass pin
*/
void getPin(OstWorkflowContext ostWorkflowContext, String userId, OstPinAcceptInterface ostPinAcceptInterface);
Argument | Description |
---|---|
userId String |
Unique identifier of the user |
ostPinAcceptInterface OstPinAcceptInterface |
ostPinAcceptInterface.pinEntered() should be called to pass the PIN back to SDK. For some reason if the developer wants to cancel the current workflow they can do it by calling ostPinAcceptInterface.cancelFlow() |
/**
* Inform SDK user about invalid pin
* Developers should show invalid pin error and ask for pin again on this callback
*
* @param ostWorkflowContext holds work flow type
* @param userId Id of user whose password and pin are needed.
* @param ostPinAcceptInterface to pass another pin
*/
void invalidPin(OstWorkflowContext ostWorkflowContext, String userId, OstPinAcceptInterface ostPinAcceptInterface);
Argument | Description |
---|---|
userId String |
Unique identifier of the user |
ostPinAcceptInterface OstPinAcceptInterface |
ostPinAcceptInterface.pinEntered() should be called to again pass the PIN back to SDK. For some reason if the developer wants to cancel the current workflow they can do it by calling ostPinAcceptInterface.cancelFlow() |
/**
* Inform SDK user that entered pin is validated.
* Developers should dismiss pin dialog on this callback
*
* @param ostWorkflowContext holds work flow type
* @param userId Id of user whose pin and password has been validated.
*/
void pinValidated(OstWorkflowContext ostWorkflowContext, String userId);
Argument | Description |
---|---|
userId String |
Unique identifier of the user |
/**
* Inform SDK user about workflow core api call
* @param ostWorkflowContext info about workflow type
* @param ostContextEntity info about entity
*/
void requestAcknowledged(OstWorkflowContext ostWorkflowContext, OstContextEntity ostContextEntity)
Argument | Description |
---|---|
ostWorkflowContext OstWorkflowContext |
Information about the workflow |
ostContextEntity OstContextEntity |
Information about the entity |
/**
* Inform SDK user the the flow is complete
*
* @param ostWorkflowContext workflow type
* @param ostContextEntity status of the flow
* @see OstContextEntity
*/
void flowComplete(OstWorkflowContext ostWorkflowContext, OstContextEntity ostContextEntity)
Argument | Description |
---|---|
ostWorkflowContext OstWorkflowContext |
Information about the workflow |
ostContextEntity OstContextEntity |
Information about the entity |
/**
* Inform SDK user that flow is interrupted with errorCode
* Developers should dismiss pin dialog (if open) on this callback
*
* @param ostWorkflowContext workflow type
* @param ostError reason of interruption
*/
void flowInterrupt(OstWorkflowContext ostWorkflowContext, OstError ostError)
Argument | Description |
---|---|
ostWorkflowContext OstWorkflowContext |
Information about the workflow |
ostError OstError |
ostError object will have details about the error that interrupted the flow |
Api to get user balance. Balance of only current logged-in user can be fetched.
Parameters
parameter userId: User Id of the current logged-in user.
parameter callback: callback where to receive data/error.
getBalance(userId, callback)
OstJsonApi.getBalance(userId, new OstJsonApiCallback() {
@Override
public void onOstJsonApiSuccess(@Nullable JSONObject data) { }
@Override
public void onOstJsonApiError(@NonNull OstError err, @Nullable JSONObject response) { }
}
);
Api to get Price Points.
It will provide latest conversion rates of base token to fiat currency.
Parameters
parameter userId: User Id of the current logged-in user.
parameter callback: callback where to receive data/error.
getPricePoints(userId, callback)
OstJsonApi.getPricePoints(userId, new OstJsonApiCallback() {
@Override
public void onOstJsonApiSuccess(@Nullable JSONObject data) { }
@Override
public void onOstJsonApiError(@NonNull OstError err, @Nullable JSONObject response) { }
}
);
Api to get user balance and Price Points. Balance of only current logged-in user can be fetched.
It will also provide latest conversion rates of base token to fiat currency.
Parameters
parameter userId: User Id of the current logged-in user.
parameter callback: callback where to receive data/error.
getBalanceWithPricePoints(userId, callback)
OstJsonApi.getBalanceWithPricePoints(userId, new OstJsonApiCallback() {
@Override
public void onOstJsonApiSuccess(@Nullable JSONObject data) { }
@Override
public void onOstJsonApiError(@NonNull OstError err, @Nullable JSONObject response) { }
}
);
Api to get user transactions. Transactions of only current logged-in user can be fetched.
Parameters
parameter userId: User Id of the current logged-in user.
parameter requestPayload: request payload. Such as next-page payload, filters etc.
parameter callback: callback where to receive data/error.
getTransactions(userId, callback)
OstJsonApi.getTransactions(userId, requestPayload, new OstJsonApiCallback() {
@Override
public void onOstJsonApiSuccess(@Nullable JSONObject data) { }
@Override
public void onOstJsonApiError(@NonNull OstError err, @Nullable JSONObject response) { }
}
);
Api to get status of pending ongoing recovery.
Parameters
parameter userId: User Id of the current logged-in user.
parameter callback: callback where to receive data/error.
getPendingRecovery(userId, callback)
OstJsonApi.getPendingRecovery(userId, requestPayload, new OstJsonApiCallback() {
@Override
public void onOstJsonApiSuccess(@Nullable JSONObject data) { }
@Override
public void onOstJsonApiError(@NonNull OstError err, @Nullable JSONObject response) { }
}
);
Callbacks to be implemented by application before calling any of the above OstJsonApis.
/**
* Inform SDK user about Success of OstJsonApi
* @param data Response data
*/
public void onOstJsonApiSuccess(@Nullable JSONObject data) { }
Argument | Description |
---|---|
data JSONObject |
Api Response data |
/**
* Inform SDK user about Failure of OstJsonApi
* @param err OstError object containing error details
* @param response Api response
*/
public void onOstJsonApiError(@NonNull OstError err, @Nullable JSONObject response) { }
Argument | Description |
---|---|
err OstError |
OstError object containing error details |
response JSONObject |
Api Response |
User Activity | App State | User Status | Device Status | Session status |
---|---|---|---|---|
Installs app for the first time | Not Login | CREATED | UNREGISTED | NA |
Login in the app for the first time | Log In | CREATED | REGISTERED | NA |
Initiate Activate Wallet by entering pin | Activating Wallet | ACTIVATING | AUTHORIZING | INITIALIZING |
Activates Wallet after waiting | Activated Wallet | ACTIVATED | AUTHORIZED | AUTHORISED |
Performs transactions | Activated Wallet | ACTIVATED | AUTHORIZED | AUTHORISED |
Session get expired | Activated Wallet | ACTIVATED | AUTHORIZED | EXPIRED |
Logout all Sessions | Activated Wallet | ACTIVATED | AUTHORIZED | REVOKING -> REVOKED |
Add Session | Activated Wallet | ACTIVATED | AUTHORIZED | INITIALIZING -> AUTHORISED |
Log out from app | Not Login | ACTIVATED | AUTHORIZED | AUTHORISED |
Log in back to App | Activated Wallet | ACTIVATED | AUTHORIZED | AUTHORISED |
Reinstall the App | No Login | CREATED | UNREGISTED | NA |
Login in the app | Log In | ACTIVATED | REGISTERED | NA |
Recover Wallet Or Add Wallet | Activating Wallet | ACTIVATED | AUTHORIZING -> AUTHORISED | NA |
Revoked Device from other device | Activated Wallet | ACTIVATED | REVOKING -> REVOKED | NA |
To get real time updates of entities like ongoing activation Or transactions, server side sdk's WebHooks services can be used.
- Check whether User need Activation.
- Check whether Wallet need Device Addition Or Recovery.
- For device addition, the current Device which is to be Authorized should used OstSdk.getAddDeviceQRCode to generate QR code And OstSdk.performQRAction() method should be used to process that QR from AUTHORIZED deivce.
- Device can also be added through OstSdk.authorizeCurrentDeviceWithMnemonics() by passing AUTHORIZED device mnemonics.
- Or Device can be recovered through OstSdk.initiateDeviceRecovery() by passing Device address of the Device to be recovered from.
if (!(ostUser.isActivated() || ostUser.isActivating())) {
//TODO:: Wallet need Activation
} else if (ostUser.isActivated() && ostUser.getCurrentDevice().canBeAuthorized()) {
//TODO:: Ask user whether he wants to Add device through QR or Mnemonics Or want to recover device.
} else {
//TODO:: App Dashboard
}
- TokenHolder Balance can be shown in Token currency or in Fiat currency.
- For Token currency conversion, the fetched balance is in Wei unit, which needs to be converted to Base unit.
- For Fiat currency conversion, the fetched balance first need to be converted to fiat equivalent using current converion rate from price points and then to its Base unit.
OstJsonApi.getBalanceWithPricePoints(userId, new OstJsonApiCallback() {
@Override
public void onOstJsonApiSuccess(@Nullable JSONObject jsonObject) {
if ( null != jsonObject ) {
String balance = "0";
JSONObject pricePoint = null;
try{
JSONObject balanceData = jsonObject.getJSONObject(jsonObject.getString("result_type"));
balance = balanceData.getString("available_balance");
pricePoint = jsonObject.optJSONObject("price_point");
} catch(Exception e){
}
//To user balance in token currency with two decimals.
convertWeiToTokenCurrency(balance);
//To user balance in fiat(Dollar) with two decimals.
convertBTWeiToFiat(balance, pricePoint)
} else {
//Todo:: Show fetch error
}
}
@Override
public void onOstJsonApiError(@NonNull OstError err, @Nullable JSONObject data) {
//Todo:: Show fetch error
}
});
public static String convertWeiToTokenCurrency(String balance) {
if (null == balance) return "0";
OstToken token = OstSdk.getToken(AppProvider.getTokenId());
Integer decimals = Integer.parseInt(token.getBtDecimals());
BigDecimal btWeiMultiplier = new BigDecimal(10).pow(decimals);
BigDecimal balance = new BigDecimal(balance).divide(btWeiMultiplier);
return balance.setScale(2, RoundingMode.HALF_UP).toString();
}
public static String convertBTWeiToFiat(String balance, JSONObject pricePointObject) {
if (null == balance || null == pricePointObject) return null;
try{
OstToken token = OstSdk.getToken(AppProvider.getTokenId());
double pricePointOSTtoUSD = pricePointObject.getJSONObject(token.getBaseToken()).getDouble("USD");
int fiatDecimalExponent = pricePointObject.getJSONObject(token.getBaseToken()).getInt("decimals");
BigDecimal fiatToEthConversionFactor = new BigDecimal("10").pow(fiatDecimalExponent);
BigDecimal tokenToFiatMultiplier = calTokenToFiatMultiplier(pricePointOSTtoUSD, fiatDecimalExponent, token.getConversionFactor(), Integer.parseInt(token.getBtDecimals()));
BigDecimal fiatBalance = new BigDecimal(balance).multiply(tokenToFiatMultiplier);
return fiatBalance.divide(fiatToEthConversionFactor, 2, RoundingMode.DOWN).toString();
} catch (Exception e){
return null;
}
}
- Download AAR file from S3 Download link
- Create libs folder under app directory in your application project.
- In libs folder add your downloaded aar file.
- Add aar lib dependency to your build.gradle file
implementation files('libs/ostsdk-release.aar')
- Also add dependencies of ostsdk in you build.gradle
dependencies {
// your app dependencies
//--- Section to Copy ----
// Room components
implementation "android.arch.persistence.room:runtime:1.1.1"
annotationProcessor "android.arch.persistence.room:compiler:1.1.1"
implementation 'com.madgag.spongycastle:core:1.56.0.0'
implementation 'org.web3j:core:4.1.0-android'
// Lifecycle components
implementation "android.arch.lifecycle:extensions:1.1.1"
annotationProcessor "android.arch.lifecycle:compiler:1.1.1"
// https://mvnrepository.com/artifact/com.google.guava/guava
implementation 'com.google.guava:guava:18.0'
// Zxing barcode dependency
implementation 'me.dm7.barcodescanner:zxing:1.9.8'
//---Section to Copy ----
}
- Clean and then Build your Android project.