diff --git a/docs/antora.yml b/docs/antora.yml new file mode 100644 index 0000000..c32f2d1 --- /dev/null +++ b/docs/antora.yml @@ -0,0 +1,5 @@ +name: client-sdk-react-native +title: Ost Client (Mobile Wallet) SDK React Native +version: '1.0' +nav: +- modules/ROOT/nav.adoc diff --git a/docs/modules/ROOT/assets/images/redemptionFlow.png b/docs/modules/ROOT/assets/images/redemptionFlow.png new file mode 100644 index 0000000..d9ab106 Binary files /dev/null and b/docs/modules/ROOT/assets/images/redemptionFlow.png differ diff --git a/docs/modules/ROOT/assets/images/setup_device_workflow.svg b/docs/modules/ROOT/assets/images/setup_device_workflow.svg new file mode 100644 index 0000000..2e3b9b2 --- /dev/null +++ b/docs/modules/ROOT/assets/images/setup_device_workflow.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/modules/ROOT/assets/images/wallet_details.png b/docs/modules/ROOT/assets/images/wallet_details.png new file mode 100644 index 0000000..ca6a0a0 Binary files /dev/null and b/docs/modules/ROOT/assets/images/wallet_details.png differ diff --git a/docs/modules/ROOT/assets/images/wallet_settings.png b/docs/modules/ROOT/assets/images/wallet_settings.png new file mode 100644 index 0000000..4ae6f9d Binary files /dev/null and b/docs/modules/ROOT/assets/images/wallet_settings.png differ diff --git a/docs/modules/ROOT/examples/initialize.js b/docs/modules/ROOT/examples/initialize.js new file mode 100644 index 0000000..7d856e7 --- /dev/null +++ b/docs/modules/ROOT/examples/initialize.js @@ -0,0 +1,8 @@ +/** + * Initialize wallet sdk + * @param {String} endpoint - Ost Platform endpoint + * @param {function} Callback function with error and success status. + * @public + */ + OstWalletSdk.initialize( endpoint, + (error, success) => {}) \ No newline at end of file diff --git a/docs/modules/ROOT/examples/ost-sdk-theme-config.js b/docs/modules/ROOT/examples/ost-sdk-theme-config.js new file mode 100644 index 0000000..ce8bc18 --- /dev/null +++ b/docs/modules/ROOT/examples/ost-sdk-theme-config.js @@ -0,0 +1,68 @@ +export default { + + "nav_bar_logo_image": { + "asset_name": "header_icon" + }, + + "c1": { + "size": 14, + "color": "#484848", + "system_font_weight": "bold", + "alignment": "left" + }, + "b1":{ + "color":"#ffffff", + "size":15 + }, + + "c2": { + "size": 12, + "color": "#6F6F6F", + "system_font_weight": "regular", + "alignment": "left" + }, + + "navigation_bar": { + "tint_color": "#61B2C9" + }, + + "navigation_bar_header": { + "tint_color": '#ffffff' + }, + + "icons": { + "close": { + "tint_color": "#ffffff" + }, + "back":{ + "tint_color": "#ffffff", + "source" : null + } + }, + + "cell_separator": { + "color": "#DBDBDB" + }, + + "link": { + "size": 14, + "color": "#007aff", + "system_font_weight": "medium", + "alignment": "left", + }, + + "status": { + "size": 14, + "color": "#0F9D58", + "system_font_weight": "regular", + "alignment": "left", + }, + + "form_field": { + "size":15, + "system_font_weight":"regular", + "color":"#484848", + "border_color": "#484848", + "alignment": "left" + } +} diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc new file mode 100644 index 0000000..15d54b1 --- /dev/null +++ b/docs/modules/ROOT/nav.adoc @@ -0,0 +1,13 @@ +* xref:index.adoc[Overview] +* xref:android-setup.adoc[Android Setup] +* xref:ios-setup.adoc[iOS Setup] +* xref:OstCoreWorkflows.adoc[Ost Core Workflows] +* xref:OstWalletUI.adoc[Ost Wallet UI] +* xref:OstWalletSettings.adoc[Ost Wallet Settings] +* xref:OstWalletSettingsConfig.adoc[Ost Wallet Settings Config] +* xref:OstRedemptionFlow.adoc[Ost Redemption Flow] +* xref:OstRedemptionConfig.adoc[Ost Redemption Config] +* xref:OstTransactionHelper.adoc[Ost Transaction Helper] +* xref:OstTransactionConfig.adoc[Ost Transaction Config] +* xref:OstWalletSdkGetMethods.adoc[Ost Wallet SDK Get Methods] +* xref:OstJsonAPI.adoc[Ost JSON API] \ No newline at end of file diff --git a/docs/modules/ROOT/pages/AndroidSetup.adoc b/docs/modules/ROOT/pages/AndroidSetup.adoc new file mode 100644 index 0000000..089c726 --- /dev/null +++ b/docs/modules/ROOT/pages/AndroidSetup.adoc @@ -0,0 +1,79 @@ += Android set-up required for Ost React Native SDK +:doctype: book + +== 1. Linking the Ost React Native SDK + +=== Automatic Linking + +[source,bash] +---- +react-native link @ostdotcom/ost-wallet-sdk-react-native +---- + +=== Manual Linking + +. Open up `+./android/app/src/main/java/[...]/MainApplication.java+`. + ** Add `import com.ostwalletrnsdk.OstWalletRnSdkPackage;` to the imports at the top of the file. + ** Add `new OstWalletRnSdkPackage()` to the list returned by the `getPackages()` method +. Append the following lines to `./android/settings.gradle`: ` include ':ost-wallet-sdk-react-native' project(':ost-wallet-sdk-react-native').projectDir = new File(rootProject.projectDir, '../node_modules/ost-wallet-sdk-react-native/android') ` +. Insert the following lines inside the dependencies block in `./android/app/build.gradle`: ``` compile project(':ost-wallet-sdk-react-native') + +== 2. Changing `minSdkVersion` in './android/build.gradle' file + +Change the `minSdkVersion` to 22 in `android/build.gradle` + +---- +android { + defaultConfig { + minSdkVersion 22 + ... + ... + ... + } +} +---- + +== 3. Create SDK configuration file + +Create file `./android/app/src/main/assets/ost-mobilesdk.json` with application specific configurations using the json below as an example + +[source,json] +---- +{ + "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 +} +---- + +. BlockGenerationTime: The time in seconds it takes to mine a block on auxiliary chain. +. PricePointTokenSymbol: This is the symbol of base currency. +So its value will be OST. +. PricePointCurrencySymbol: It is the symbol of quote currency used in price conversion. +. RequestTimeoutDuration: Request timeout in seconds for https calls made by ostWalletSdk. +. PinMaxRetryCount: Maximum retry count to get the wallet Pin from user. +. SessionBufferTime: Buffer expiration time for session keys in seconds. +Default value is 3600 seconds. +. UseSeedPassword: The seed password is salt to PBKDF2 used to generate seed from the mnemonic. +When UseSeedPassword set to `true`, different deterministic salts are used for different keys. + +*NOTE: These configurations are MANDATORY for successful operation. +Failing to set them will significantly impact usage.* + += Debug builds with Android 9 (API level 28) + +Starting with Android 9 (API level 28), https://developer.android.com/training/articles/security-config#CleartextTrafficPermitted[cleartext support] is disabled by default. +On the other hand, Ost Wallet Android Sdk leverages on *Public Key Pinning* to ensure the authenticity of a Ost Platform server's public key used in TLS sessions using https://github.com/datatheorem/TrustKit-Android[TrustKit]. +As TrustKit can only be inititialized with application's https://developer.android.com/training/articles/security-config[network security configuration], sdk initialization fails. +To work-around this issues, application needs to have TrustKit as a dependency and initialize it. + +Please refer to https://github.com/ostdotcom/ost-wallet-sdk-android/blob/develop/documentation/TrustKitPublickeyPinning.md[Public Key Pinning Using TrustKit] documentation. + += Next Steps + +. link:../README.md#sdk-usage[SDK Usage] +. link:../README.md#sdk-methods[SDK Methods] +. link:../README.md#sdk-workflow-callbacks[SDK Callbacks] diff --git a/docs/modules/ROOT/pages/CHANGELOG.md.adoc b/docs/modules/ROOT/pages/CHANGELOG.md.adoc new file mode 100644 index 0000000..62a9418 --- /dev/null +++ b/docs/modules/ROOT/pages/CHANGELOG.md.adoc @@ -0,0 +1,146 @@ += OST Wallet SDK Changelog + +== Version 2.4.1 + +* User can authorize external session by scanning QR-Code. +To use `Authorize session by scanning QR code`, please update downstream sdk. ++ iOS: v2.4.1 + Android: v2.4.1 +* User can pass QR-Code payload to perform QR-Code actions without opening Scanner in OstWalletUI. +This functionality is available for `scanQRCodeToAuthorizeSession`, `scanQRCodeToExecuteTransaction`, `scanQRCodeToAuthorizeDevice`, + +== Version 2.4.0 + +* OstRedemption UI component is now available in SDK. +To use `OstRedemption`, please update downstream sdk. ++ iOS:``v2.4.0`` + Android:``v2.4.0`` +* `getRedeemableSkus` and `getRedeemableSkuDetails` apis added in `OstJsonApi`. + +== Version 2.3.14 + +* ReadMe updates + +* Removed unused imports + +* Peer dependency fixes + + +== Version 2.3.12 + +* OstWalletSettings UI component is now available in SDK. +To use `OstWalletSettings`, please update downstream sdk. ++ iOS:``v2.3.6`` + Android:``v2.3.8`` + +== Version 2.3.12-beta.1 + +* OstWalletSettings UI component is now available in SDK. +To use `OstWalletSettings`, please update downstream sdk. ++ iOS:``v2.3.6-beta-1`` + Android:``v2.3.8-beta.1`` + +== Version 2.3.11 + +=== Bug Fix: + +* In Android inaccurate error is thrown when application runs out of memory during recover device workflow. ++ Downstream Android Sdk updated to `v2.3.7` + +== Version 2.3.10 + +* OstWalletSdk supports custom loader for OstWalletUI. +To use custom loader, please update downstream sdk. ++ iOS:``v2.3.5`` + Android:``v2.3.6`` + +== Version 2.3.9 + +* Downstream iOS Sdk updated to `v2.3.4` + +== Version 2.3.8 + +* Removed jitpack.io dependency. + +== Version 2.3.7 + +* Downstream iOS Sdk updated to `v2.3.3` + +== Version 2.3.6 + +* Downstream Android Sdk updated to `v2.3.5` + +== Version 2.3.5 + +* Downstream Android Sdk updated to `v2.3.4` + +== Version 2.3.4 + +* Downstream Android Sdk updated to `v2.3.2` + +== Version 2.3.3 + +=== Bug Fix: + +* OstWalletUIWorkflowCallback signature updated. + +== Version 2.3.2 + +=== Bug Fix: + +* Fixed a bug, where `ostApiError.getApiError` always returned an empty object. + +== Version 2.3.1 + +=== Feature: + +* OstWalletUI now supports + ** get add device QR-Code + ** scan QR-Code to authorize device + ** scan QR-Code to execute transaction + ** authorize current device with mnemonics +* Api provided to fetch current device from OstPlatform. +* Now supports getting active sessions from Sdk. + +== Version 2.3.0 + +=== Feature: + +* OstWalletSdk now contains UI. +* UI components can be modified. +* Languages for UI workflow components can be modified. +* OstWalletUI now supports + ** activate user + ** create session + ** get device mnemonics + ** revoke device + ** reset pin + ** initiate device recovery + ** abort device recovery + ** update biometric preference + +== Version v2.2.4 + +=== Bug Fix: + +* iOS: Inconsistent signature generation fix. + +== Version v2.2.3 + +* Android: Added support for AndroidX + +== Version v2.2.2 + +=== Bug Fix: + +* iOS: Scanning unrecognized QR codes no longer causes the SDK to crash + +== Version v2.2.1 + +=== Bug Fix: + +* Fix `fetchDevice` cache issue for `initiateDeviceRecovery` +* Add `No Network Access` error to OstApiError ++ +=== Security Enhancements +* Implemented public-key pinning for api.ost.com + +== Version v2.2.0 + +=== Changes: + +* Added Multi Currency Feature which allows developers to specify fiat-currency at runtime while executing a transaction. +* Added OstJsonApi that allows developers to fetch data from Ost Platform. +Please see README.MD for supported Api(s). diff --git a/docs/modules/ROOT/pages/OstCoreWorkflows.adoc b/docs/modules/ROOT/pages/OstCoreWorkflows.adoc new file mode 100644 index 0000000..4a8bcf2 --- /dev/null +++ b/docs/modules/ROOT/pages/OstCoreWorkflows.adoc @@ -0,0 +1,624 @@ += Ost Core Workflow APIs + +Ost core workflows api do not use any UI components, thereby giving complete control to the developers. +The xref:./OstWalletUI.adoc[`OstWalletSdkUI`] also uses Ost Core Workflows. + +== Table of Contents + +* <> +* <> + ** <> + ** <> + ** <> + *** <> + *** <> + *** <> + *** <> + *** <> + *** <> + *** <> + *** <> +* <> + ** <> + *** <> + *** <> + *** <> + *** <> + *** <> + *** <> + *** <> + *** <> + *** <> + *** <> + *** <> + *** <> + *** <> + ** <> + +== Import the OstWalletSdk + +To use the core workflow APIs, import the `OstWalletSdk` from '@ostdotcom/ost-wallet-sdk-react-native'. + +[source,javascript] +---- +import {OstWalletSdk} from '@ostdotcom/ost-wallet-sdk-react-native'; +---- + +== Create Workflow Callback + +The core workflows communicates with the application using callbacks. +A base callback class `OstWalletWorkFlowCallback` is given as a part of the SDK. +The base callback class gives only declaration of callback functions. +A detailed overview of callback functions is available in the later part of this readme. + +=== OstWalletWorkFlowCallback Interface + +[source,javascript] +---- +import { OstWalletWorkFlowCallback } from '@ostdotcom/ost-wallet-sdk-react-native'; + +class OstWalletSdkCallbackImplementation extends OstWalletWorkFlowCallback { + constructor() { + super(); + } + + registerDevice(apiParams, ostDeviceRegistered) {} + + getPin(ostWorkflowContext, ostContextEntity, ostPinAccept) {} + + invalidPin(ostWorkflowContext, ostContextEntity, ostPinAccept) {} + + pinValidated(ostWorkflowContext, ostContextEntity) {} + + flowComplete( ostWorkflowContext, ostContextEntity ) {} + + flowInterrupt(ostWorkflowContext, ostError ) {} + + requestAcknowledged(ostWorkflowContext, ostContextEntity) {} + + verifyData(ostWorkflowContext, ostContextEntity, ostVerifyData) {} +} + +export default OstWalletSdkCallbackImplementation; +---- + +*Developers are expected to implement a new class for each workflow.* + +=== An example of callback implementation + +[source,javascript] +---- + +import {OstWalletWorkFlowCallback} from '@ostdotcom/ost-wallet-sdk-react-native'; + +class OstWalletSdkCallbackImplementation extends OstWalletWorkFlowCallback { + constructor() { + super(); + } + + flowComplete(ostWorkflowContext , ostContextEntity) { + console.log('flowComplete ostWorkflowContext', ostWorkflowContext, "ostContextEntity- ", ostContextEntity); + if(Actions.currentScene !== "HomePage"){ + Actions.popTo("HomePage"); + } + if(ostWorkflowContext){ + let wfType = ostWorkflowContext.WORKFLOW_TYPE; + if( wfType !== "SETUP_DEVICE") { + Alert.alert(`${wfType} Complete!`); + } + } + store.dispatch(setLoading(false)); + } + + flowInterrupt(ostWorkflowContext , ostError) { + console.log('flowInterrupt ostWorkflowContext', ostWorkflowContext , "ostError" , ostError ); + if (ostError) { + let displayError = ostError.getErrorMessage(), + apiError, errorData; + if(ostError.isApiError()){ + apiError = ostError.getApiErrorMessage(); + if(apiError && apiError.includes('err.error_data')){ + apiError = ''; + } + errorData = ostError.getApiErrorData(); + if(errorData && errorData.length > 0){ + for(let i=0; i} tokenHolderAddresses - Token holder addresses of amount receiver. + * @param {Array} amounts -Amounts corresponding to tokenHolderAddresses to be transfered + * @param {String} ruleName - Rule name to be executed. + * @param {object} meta - additional data. + * @param {OstWalletWorkFlowCallback} workflow - callback implementation instances for application communication + * @public + */ + + OstWalletSdk.executeTransaction( userId, + tokenHolderAddresses, + amounts, + ruleName, + meta, + workflow) +---- + +==== getDeviceMnemonics + +The mnemonic phrase represents a human-readable way to authorize a new device. +This phrase is 12 words long. + +[source,javascript] +---- +/** + * Get Device mnemonics + * @param {String} userId - Ost User id + * @param {OstWalletWorkFlowCallback} workflow - callback implementation instances for application communication + * @public + */ + OstWalletSdk.getDeviceMnemonics( userId, + workflow) +---- + +==== authorizeCurrentDeviceWithMnemonics + +A user that has stored their mnemonic phrase can enter it on a new mobile device and authorize that device to be able to control their tokens. + +[source,javascript] +---- + /** + * Authorize user device with mnemonics + * @param {String} userId - Ost User id + * @param {String} mnemonics - string of mnemonics + * @param {OstWalletWorkFlowCallback} workflow - callback implementation instances for application communication + * @public + */ + + OstWalletSdk.authorizeCurrentDeviceWithMnemonics(userId, + mnemonics, + workflow) +---- + +==== performQRAction + +QR codes can be used to encode transaction data for authorizing devices and making purchases via webstores, etc. +This method can be used to process the information scanned off a QR code and act on it. + +[source,javascript] +---- +/** + * Perform QR action + * @param {String} userId - Ost User id + * @param {String} data - Json string of payload is scanned by QR-Code. + * @param {OstWalletWorkFlowCallback} workflow - callback implementation instances for application communication + * @public + */ + OstWalletSdk.performQRAction(userId, + data, + workflow) +---- + +==== resetPin + +The user's PIN is set when activating the user. +This method supports re-setting a PIN and re-creating the recoveryOwner. + +[source,javascript] +---- +/** + * Reset user pin + * @param {String} userId - Ost User id + * @param {String} appSalt - Passphrase prefix provided by application server + * @param {String} currentPin - user current pin + * @param {String} newPin - user new pin + * @param {OstWalletWorkFlowCallback} workflow - callback implementation instances for application communication + * @public + */ + OstWalletSdk.resetPin( userId, + appSalt, + currentPin, + newPin, + workflow ) +---- + +==== initiateDeviceRecovery + +A user can control their tokens using their authorized device(s). +If a user loses their authorized device, the user can recover access to her tokens by authorizing a new device by initiating the recovery process. + +[source,javascript] +---- +/** + * Initiate device recovery + * @param {String} userId - Ost User id + * @param {String} pin - user current pin + * @param {String} appSalt - Passphrase prefix provided by application server + * @param {String} deviceAddressToRecover - Device address which wants to recover + * @param {OstWalletWorkFlowCallback} workflow - callback implementation instances for application communication + * @public + */ +OstWalletSdk.initiateDeviceRecovery( userId, + pin, + appSalt, + deviceAddressToRecover, + workflow ) +---- + +==== abortDeviceRecovery + +To abort an initiated device recovery. + +[source,javascript] +---- +/** + * Abort device recovery + * @param {String} userId - Ost User id + * @param {String} pin - user current pin + * @param {String} appSalt - Passphrase prefix provided by application server + * @param {OstWalletWorkFlowCallback} workflow - callback implementation instances for application communication + * @public + */ +OstWalletSdk.abortDeviceRecovery(userId, + pin , + appSalt , + workflow ) +---- + +==== logoutAllSessions + +To revoke all sessions associated with provided userId. + +[source,javascript] +---- +/** + * Logout user all sessions + * @param {String} userId - Ost User id + * @param {OstWalletWorkFlowCallback} workflow - callback implementation instances for application communication + * @public + */ +OstWalletSdk.logoutAllSessions(userId, + workflow ) +---- + +==== revokeDevice + +To unauthorize the current device. + +[source,javascript] +---- +/** + * revokeDevice + * @param {String} userId - Ost User id + * @param {String} deviceAddress - device address + * @param {OstWalletWorkFlowCallback} workflow - callback implementation instances for application communication + * @public + */ + OstWalletSdk.revokeDevice( userId , + deviceAddress , + workflow) +---- + +==== updateBiometricPreference + +To enable or disable biometrics. + +[source,javascript] +---- +/** + * Update biometric prederence + * @param {String} userId - Ost User id + * @param {boolean} enable - to enable biometric prefernce + * @param {OstWalletWorkFlowCallback} workflow - callback implementation instances for application communication + * @public + */ + OstWalletSdk.updateBiometricPreference( userId , enable ,workflow ) +---- + +=== Execute a workflow + +To execute a workflow, you need to pass an instance of `OstWalletSdkCallbackImplementation` class. +The callback implementation will be different for each workflow available in the SDK. + +[source,javascript] +---- + +import OstWalletWorkflowCallback from './OstWalletSdkCallbackImplementation'; + +onLogoutAllSessions() { + AsyncStorage.getItem('user').then((user) => { + user = JSON.parse(user); + // Note: logoutAllSessions will revoke all sessions keys from all the devices of the user. + OstWalletSdk.logoutAllSessions(user.user_details.user_id, new OstWalletWorkflowCallback(), console.warn); + }); +} +---- diff --git a/docs/modules/ROOT/pages/OstJsonApi.adoc b/docs/modules/ROOT/pages/OstJsonApi.adoc new file mode 100644 index 0000000..1857aaa --- /dev/null +++ b/docs/modules/ROOT/pages/OstJsonApi.adoc @@ -0,0 +1,853 @@ += OST JSON APIs + +OST JSON APIs are a set of _asynchronous_ methods that make API calls to OST Platform servers. + +== Table of Contents + +* <> +* <> +* <> +* <> + ** <> + *** <> + *** <> + ** <> + *** <> + *** <> + ** <> + *** <> + *** <> + ** <> + *** <> + *** <> + ** <> + *** <> + *** <> + *** <> + ** <> + *** <> + *** <> +* <> + ** <> + *** <> + *** <> + ** <> + *** <> + *** <> + ** <> + *** <> + *** <> + +++++++++++++ + +== Before We Begin + +* Although it is *NOT RECOMMENDED*, but if your app needs to allow multiple users to login on same device, the app must: + ** ensure to pass the `userId` of the currently *logged-in and authenticated* user. + ** ensure that the user has not logged-out *before* processing/displaying the response. +* App must link:../README.md#initializing-the-sdk[initialize] the SDK _*before*_ initiating any JSON API. +* App must perform link:../README.md#setupdevice[setupDevice] workflow _*before*_ initiating any JSON API. +* All `OstJsonApi` methods expect `userId` as first parameter because all requests need to be signed by the user's API key. +* It's always good to check if the device can make API calls by calling `OstWalletSdk.getCurrentDeviceForUserId` method. + ** Any device with status `REGISTERED`, `AUTHORIZING`, `AUTHORIZED`, `RECOVERING` or `REVOKING` can make this API call. + +++++++++++++ + +== JSON API Types + +The JSON APIs can be categorized into 2 groups. + +* <> - The APIs that get entities (e.g. +current-device, price-point, balance, etc.) +* <> - The APIs that get list of entities and support pagination (e.g. +device list, transactions) + +++++++++++++ + +== Importing OstJsonApi + +Use the following code to import `OstJsonApi` + +---- +import {OstJsonApi} from '@ostdotcom/ost-wallet-sdk-react-native'; +---- + +++++++++++++ + +== Entity API + +++++++++++++ + +=== Get Current Device + +API to get user's current device. + +____ +While the equivalent getter method `OstWalletSdk.getCurrentDeviceForUserId` gives the data stored in SDK's database, this method makes an API call to OST Platform. +____ + +++++++++++++ + +.Usage +[source,javascript] +---- +/* + Please update userId as per your needs. + Since this userId does not belong to your economy, you will get an error if you do not change it. +*/ +let userId = "71c59448-ff77-484c-99d8-abea8a419836"; + +/** + * API to get user's current device. + * @param {String} userId - Ost User id + * @param {function} Success callback with success data + * @param {function} Failure callback with error and failure response + * @public + */ + +OstJsonApi.getCurrentDeviceForUserId( + userId, + (data) => { + console.log(data); + }, + (error, response) => {} +) +---- + +++++++++++++ + +.Sample Response +[source,json] +---- +{ + "device": { + "updated_timestamp": 1566832473, + "status": "AUTHORIZED", + "api_signer_address": "0x674d0fc0d044f085a87ed742ea778b55e298b429", + "linked_address": "0x0000000000000000000000000000000000000001", + "address": "0x8d92cf567191f07e5c1b487ef422ff684ddf5dd3", + "user_id": "71c59448-ff77-484c-99d8-abea8a419836" + }, + "result_type": "device" +} +---- + +++++++++++++ + +=== Get Balance + +API to get user's balance. + +++++++++++++ + +.Usage +[source,javascript] +---- +/* + Please update userId as per your needs. + Since this userId does not belong to your economy, you will get an error if you do not change it. +*/ +let userId = "71c59448-ff77-484c-99d8-abea8a419836"; + +/** + * Api to get user balance + * @param {String} userId - Ost User id + * @param {function} Success callback with success data + * @param {function} Failure callback with error and failure response + * @public + */ + +OstJsonApi.getBalanceForUserId( + userId, + (data) => { + console.log(data); + }, + (error, response) => {} +) +---- + +++++++++++++ + +.Sample Response +[source,json] +---- +{ + "balance": { + "updated_timestamp": 1566832497, + "unsettled_debit": "0", + "available_balance": "10000000", + "total_balance": "10000000", + "user_id": "71c59448-ff77-484c-99d8-abea8a419836" + }, + "result_type": "balance" +} +---- + +++++++++++++ + +=== Get Price Points + +API to get price-points of token's staking currency (OST or USDC). + +____ +This API call is generally needed to compute the current fiat value to your brand-tokens. +E.g. +displaying user's balance in fiat. +____ + +++++++++++++ + +.Usage +[source,javascript] +---- +/* + Please update userId as per your needs. + Since this userId does not belong to your economy, you will get an error if you do not change it. +*/ +let userId = "71c59448-ff77-484c-99d8-abea8a419836"; + +/** + * Api to get user balance + * @param {String} userId - Ost User id + * @param {function} Success callback with success data + * @param {function} Failure callback with error and failure response + * @public + */ + +OstJsonApi.getPricePointForUserId( + userId, + (data) => { + console.log(data); + }, + (error, response) => {} +) +---- + +++++++++++++ + +.Sample Response +[source,json] +---- +{ + "price_point": { + "USDC": { + "updated_timestamp": 1566834913, + "decimals": 18, + "GBP": 0.8201717727, + "EUR": 0.9028162679, + "USD": 1.0025110673 + } + }, + "result_type": "price_point" +} +---- + +++++++++++++ + +=== Get Balance And Price Points + +This is a convenience method that makes `OstJsonApi.getBalanceForUserId` and `OstJsonApi.getPricePointForUserId` API calls and merges the response. + +++++++++++++ + +.Usage +[source,javascript] +---- +/* + Please update userId as per your needs. + Since this userId does not belong to your economy, you will get an error if you do not change it. +*/ +let userId = "71c59448-ff77-484c-99d8-abea8a419836"; + +/** + * Api to get user balance + * @param {String} userId - Ost User id + * @param {function} Success callback with success data + * @param {function} Failure callback with error and failure response + * @public + */ + +OstJsonApi.getBalanceWithPricePointForUserId( + userId, + (data) => { + console.log(data); + }, + (error, response) => {} +) +---- + +++++++++++++ + +.Sample Response +[source,json] +---- +{ + "balance": { + "updated_timestamp": 1566832497, + "unsettled_debit": "0", + "available_balance": "10000000", + "total_balance": "10000000", + "user_id": "71c59448-ff77-484c-99d8-abea8a419836" + }, + "price_point": { + "USDC": { + "updated_timestamp": 1566834913, + "decimals": 18, + "GBP": 0.8201717727, + "EUR": 0.9028162679, + "USD": 1.0025110673 + } + }, + "result_type": "balance" +} +---- + +++++++++++++ + +=== Get Pending Recovery + +API to get user's pending recovery. +A pending recovery is created when the user recovers the device using their PIN. + +____ +This API will respond with `UNPROCESSABLE_ENTITY` API error code when user does not have any recovery in progress. +____ + +++++++++++++ + +.Usage +[source,javascript] +---- +/* + Please update userId as per your needs. + Since this userId does not belong to your economy, you will get an error if you do not change it. +*/ +let userId = "71c59448-ff77-484c-99d8-abea8a419836"; + +/** + * Api to get user balance + * @param {String} userId - Ost User id + * @param {function} Success callback with success data + * @param {function} Failure callback with error and failure response + * @public + */ +OstJsonApi.getPendingRecoveryForUserId( + userId, + (data) => { + console.log(data); + }, + (error, response) => { + console.log( error ); + if ( error.is_api_error ) { + if ( "UNPROCESSABLE_ENTITY" === String(error.api_error.code).toUppercase() ) { + console.log("User does not have any recovery in progress."); + // You can safely ignore this error. + return; + } + } + } +) +---- + +++++++++++++ + +.Sample Response +[source,json] +---- + { + "devices": [ + { + "updated_timestamp": 1566902100, + "status": "REVOKING", + "api_signer_address": "0x903ad1a1017c14b8e6b0bb1dd32d3f65a8741732", + "linked_address": "0x73722b0c0a6b6418893737e0ca33dd567e33f6aa", + "address": "0x629e13063a2aa24e2fb2a49697ef871806071550", + "user_id": "71c59448-ff77-484c-99d8-abea8a419836" + }, + { + "updated_timestamp": 1566902100, + "status": "RECOVERING", + "api_signer_address": "0x6f5b1b8df95cbc3bd8d18d6c378cef7c34644729", + "linked_address": "null", + "address": "0x33e736a4761bc07ed54b1ceb82e44dfb497f478c", + "user_id": "71c59448-ff77-484c-99d8-abea8a419836" + } + ], + "result_type": "devices" +} +---- + +++++++++++++ + +.Sample Error + +The `getPendingRecoveryForUserId` API will respond with `UNPROCESSABLE_ENTITY` API error code when user does not have any recovery in progress. + +[source,json] +---- +{ + "api_error": { + "internal_id": "***********", + "error_data": [], + "msg": "Initiate Recovery request for user not found.", + "code": "UNPROCESSABLE_ENTITY" + }, + "is_api_error": 1, + "error_message": "OST Platform Api returned error.", + "internal_error_code": "***********", + "error_code": "API_RESPONSE_ERROR" +} +---- + +++++++++++++ + +=== Get Redeemable Sku Details + +API to get redeemable sku details. + +++++++++++++ + +.Usage +[source,javascript] +---- +/* + Please update userId as per your needs. + Since this userId does not belong to your economy, you will get an error if you do not change it. +*/ +let userId = "71c59448-ff77-484c-99d8-abea8a419836"; +let skuDetailId = "2"; +let extraParams = {}; + +/** + * Api to get redeemable skus + * @param {String} userId - Ost User id + * @param {String} skuDetailId - Sku detail id got from list of Redeemable skus + * @param {Object} extraParams (@nullable). + * @param {function} Success callback with success data + * @param {function} Failure callback with error and failure response + * @public + */ + + +OstJsonApi.getRedeemableSkuDetails(userId, skuDetailId ,extraParams, (response) => { + console.log(response); + }, (error)=> { + console.log("An error has occurred while fetching redeemable sku details."); + console.log( error ); + }); +---- + +++++++++++++ + +.Sample Response +[source,json] +---- +{ + "result_type":"redemption_product", + "redemption_product":{ + "status":"active", + "images":{ + "detail":{ + "original":{ + "size":90821, + "url":"https://dxwfxs8b4lg24.cloudfront.net/ost-platform/rskus/stag-starbucks-d-original.png", + "width":150, + "height":150 + } + }, + "cover":{ + "original":{ + "size":193141, + "url":"https://dxwfxs8b4lg24.cloudfront.net/ost-platform/rskus/stag-starbucks-c-original.png", + "width":320, + "height":320 + } + } + }, + "availability":[ + { + "country_iso_code":"USA", + "country":"USA", + "currency_iso_code":"USD", + "denominations":[ + { + "amount_in_wei":"49938358", + "amount_in_fiat":5 + }, + { + "amount_in_wei":"99876717", + "amount_in_fiat":10 + }, + ... + ] + }, + { + "country_iso_code":"CAN", + "country":"Canada", + "currency_iso_code":"CAD", + "denominations":[ + { + "amount_in_wei":"37547638", + "amount_in_fiat":5 + }, + { + "amount_in_wei":"75095276", + "amount_in_fiat":10 + }, + ... + ] + }, + { + "country_iso_code":"GBR", + "country":"United Kingdom", + "currency_iso_code":"GBP", + "denominations":[ + { + "amount_in_wei":"64855011", + "amount_in_fiat":5 + }, + { + "amount_in_wei":"129710022", + "amount_in_fiat":10 + }, + ... + ] + }, + { + "country_iso_code":"IND", + "country":"India", + "currency_iso_code":"INR", + "denominations":[ + { + "amount_in_wei":"1396", + "amount_in_fiat":0.01 + }, + { + "amount_in_wei":"139609", + "amount_in_fiat":1 + }, + ... + ] + } + ], + "id":"2", + "updated_timestamp":1582024811, + "description":{ + "text":null + }, + "name":"Starbucks" + } +} +---- + +++++++++++++ + +== List API + +All `List` APIs support pagination. +The response of all `List` APIs has an extra attribute `meta`. +To determine if next page is available, the app should look at `meta.next_page_payload`. +If `meta.next_page_payload` is an empty object (`{}`), next page is not available. + +++++++++++++ + +=== Get Transactions + +API to get user's transactions. + +++++++++++++ + +.Usage +[source,javascript] +---- +/* + Please update userId as per your needs. + Since this userId does not belong to your economy, you will get an error if you do not change it. +*/ +let userId = "71c59448-ff77-484c-99d8-abea8a419836"; +let nextPagePayload = null; + +/** + * Api to get user's transactions + * @param {String} userId - Ost User id + * @param {Object} nextPagePayload (@nullable). Pass null to get first page. + * @param {function} Success callback with success data + * @param {function} Failure callback with error and failure response + * @public + */ + +OstJsonApi.getTransactionsForUserId(userId, nextPagePayload, + (response) => { + console.log(response); + // Let's check if more pages of data is available. + if ( response.meta ) { + let nextPagePayloadFromResponse = response.meta.next_page_payload || {}; + if ( Object.keys(nextPagePayloadFromResponse).length > 0 ) { + // Next page is available. + // Update nextPagePayload + nextPagePayload = nextPagePayloadFromResponse; + // To fetch the next page, pass the updated nextPagePayload. + } + } + }, + (error) => { + console.log("An error has occurred while fetching transactions."); + console.log( error ); + }); +---- + +++++++++++++ + +.Sample Response + +Please refer to the https://dev.ost.com/platform/docs/api/#transactions[Transactions Object] for a detailed description. + +[source,json] +---- +{ + "meta": { + "total_no": 14, + "next_page_payload": { + "pagination_identifier": "*****************************************************" + } + }, + "transactions": [ + { + "meta_property": { + "details": "Awesome Post", + "type": "user_to_user", + "name": "Like" + }, + "rule_name": "Direct Transfer", + "block_timestamp": 1566843589, + "block_confirmation": 969, + "transaction_fee": "94234000000000", + "gas_price": "1000000000", + "nonce": 613, + "from": "0x6ecbfdb2ebac8669c85d61dd028e698fd6403589", + "id": "4efa1b45-8890-4978-a5f4-8f9368044852", + "transfers": [ + { + "kind": "transfer", + "amount": "200000", + "to_user_id": "a87fdd7f-4ce5-40e2-917c-d80a8828ba62", + "to": "0xb29d32936280e8f05a5954bf9a60b941864a3442", + "from_user_id": "71c59448-ff77-484c-99d8-abea8a419836", + "from": "0xbf3df93b15c6933177237d9ed8400a2f41c8b8a9" + } + ], + "block_number": 3581559, + "updated_timestamp": 1566843589, + "status": "SUCCESS", + "gas_used": 94234, + "value": "0", + "to": "0xbf3df93b15c6933177237d9ed8400a2f41c8b8a9", + "transaction_hash": "0xee8033f9ea7e9bf2d74435f0b6cc172d9378670e513a2b07cd855ef7e41dd2ad" + }, + { + "meta_property": { + "details": "Nice Pic", + "type": "user_to_user", + "name": "Fave" + }, + "rule_name": "Direct Transfer", + "block_timestamp": 1566843547, + "block_confirmation": 983, + "transaction_fee": "109170000000000", + "gas_price": "1000000000", + "nonce": 612, + "from": "0x6ecbfdb2ebac8669c85d61dd028e698fd6403589", + "id": "7980ee91-7cf1-449c-bbaf-5074c2ba6b29", + "transfers": [ + { + "kind": "transfer", + "amount": "1600000", + "to_user_id": "a87fdd7f-4ce5-40e2-917c-d80a8828ba62", + "to": "0xb29d32936280e8f05a5954bf9a60b941864a3442", + "from_user_id": "71c59448-ff77-484c-99d8-abea8a419836", + "from": "0xbf3df93b15c6933177237d9ed8400a2f41c8b8a9" + } + ], + "block_number": 3581545, + "updated_timestamp": 1566843549, + "status": "SUCCESS", + "gas_used": 109170, + "value": "0", + "to": "0xbf3df93b15c6933177237d9ed8400a2f41c8b8a9", + "transaction_hash": "0x3e3bb3e25ab3a5123d1eaf20e1c31ab88bd56500c5cdfd2e32025c4df32735b3" + }, + ... + ... + ], + "result_type": "transactions" +} +---- + +++++++++++++ + +=== Get Devices + +API to get user's devices. + +++++++++++++ + +.Usage +[source,javascript] +---- +/* + Please update userId as per your needs. + Since this userId does not belong to your economy, you will get an error if you do not change it. +*/ +let userId = "71c59448-ff77-484c-99d8-abea8a419836"; +let nextPagePayload = null; + +/** + * Api to get user's device + * @param {String} userId - Ost User id + * @param {Object} nextPagePayload (@nullable). Pass null to get first page. + * @param {function} Success callback with success data + * @param {function} Failure callback with error and failure response + * @public + */ + +OstJsonApi.getDeviceListForUserId(userId, nextPagePayload, + (response) => { + console.log(response); + // Let's check if more pages of data is available. + if ( response.meta ) { + let nextPagePayloadFromResponse = response.meta.next_page_payload || {}; + if ( Object.keys(nextPagePayloadFromResponse).length > 0 ) { + // Next page is available. + // Update nextPagePayload + nextPagePayload = nextPagePayloadFromResponse; + // To fetch the next page, pass the updated nextPagePayload. + } + } + }, + (error) => { + console.log("An error has occurred while fetching devices."); + console.log( error ); + }); +---- + +++++++++++++ + +.Sample Response +[source,json] +---- +{ + "meta": { + "next_page_payload": {} + }, + "devices": [ + { + "updated_timestamp": 1566832473, + "status": "AUTHORIZED", + "api_signer_address": "0x674d0fc0d044f085a87ed742ea778b55e298b429", + "linked_address": "0x73722b0c0a6b6418893737e0ca33dd567e33f6aa", + "address": "0x8d92cf567191f07e5c1b487ef422ff684ddf5dd3", + "user_id": "71c59448-ff77-484c-99d8-abea8a419836" + }, + { + "updated_timestamp": 1566839512, + "status": "AUTHORIZED", + "api_signer_address": "0x2e12c4f6a27f7bdf8e58e628ec29bb4ce49c315e", + "linked_address": "0x0000000000000000000000000000000000000001", + "address": "0x73722b0c0a6b6418893737e0ca33dd567e33f6aa", + "user_id": "71c59448-ff77-484c-99d8-abea8a419836" + } + ], + "result_type": "devices" +} +---- + +++++++++++++ + +=== Get Redeemable Skus + +API to get redeemable skus. + +++++++++++++ + +.Usage +[source,javascript] +---- +/* + Please update userId as per your needs. + Since this userId does not belong to your economy, you will get an error if you do not change it. +*/ +let userId = "71c59448-ff77-484c-99d8-abea8a419836"; +let nextPagePayload = null; + +/** + * Api to get redeemable skus + * @param {String} userId - Ost User id + * @param {Object} nextPagePayload (@nullable). Pass null to get first page. + * @param {function} Success callback with success data + * @param {function} Failure callback with error and failure response + * @public + */ + + +OstJsonApi.getRedeemableSkus(userId, nextPagePayload , (respones) => { + console.log(response); + // Let's check if more pages of data is available. + if ( response.meta ) { + let nextPagePayloadFromResponse = response.meta.next_page_payload || {}; + if ( Object.keys(nextPagePayloadFromResponse).length > 0 ) { + // Next page is available. + // Update nextPagePayload + nextPagePayload = nextPagePayloadFromResponse; + // To fetch the next page, pass the updated nextPagePayload. + } + } + }, (error)=> { + console.log("An error has occurred while fetching redeemable skus."); + console.log( error ); + }); +---- + +++++++++++++ + +.Sample Response +[source,json] +---- +{ + "meta":{ + "next_page_payload":{ + } + }, + "result_type":"redemption_products", + "redemption_products":[ + { + "status":"active", + "updated_timestamp":1582024811, + "id":"2", + "description":{ + "text":null + }, + "images":{ + "detail":{ + "original":{ + "size":90821, + "url":"https://dxwfxs8b4lg24.cloudfront.net/ost-platform/rskus/stag-starbucks-d-original.png", + "width":150, + "height":150 + } + }, + "cover":{ + "original":{ + "size":193141, + "url":"https://dxwfxs8b4lg24.cloudfront.net/ost-platform/rskus/stag-starbucks-c-original.png", + "width":320, + "height":320 + } + } + }, + "name":"Starbucks" + }, + ... + ... + ] +} +---- diff --git a/docs/modules/ROOT/pages/OstRedemptionConfig.adoc b/docs/modules/ROOT/pages/OstRedemptionConfig.adoc new file mode 100644 index 0000000..71785fa --- /dev/null +++ b/docs/modules/ROOT/pages/OstRedemptionConfig.adoc @@ -0,0 +1,68 @@ += OstWallet Redemption Config + +== Introduction + +App developers can configure the text shown on redemption page. + +To configure the content, the sdk needs to be provided with https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/JSON[JSON object]. + +== Dictionary Data Structure + +Here is the small sample json representation of the configuration. + +[source,json] +---- +{ + "common": { + "walletIcon": null, + "storeIcon": null + }, + "skuListScreen": { + "navHeader": null, + "header": null, + "description": null + }, + "skuDetailsScreen": { + "navHeader": null + } +} +---- + +In the above example: + +* The key `common` includes options to configure the wallet icon in header and the store icon. +* The key `skuListScreen` allows to configure the navigation header and the header and description shown on the redemption store list page. +* The key `skuDetailsScreen` allows to configure the navigation header shown on the redemption store details page. + +== Redemption Config + +The following are the customizable options provided. +These can be set in the above config. + +|=== +| customizable component | Config Keys | Config Type + +| Wallet icon +| - walletIcon +| Custom icon Image to be rendered. + +| Store icon +| - storeIcon +| Custom icon Image to be rendered. + +| Skulist Header +| - skuListScreen.header +| String + +| Skulist Description +| - skuListScreen.description +| String + +| SkuDetails Screen Navigation header +| - skuDetailsScreen.navHeader +| String + +| Skulist Screen Navigation header +| - skuListScreen.navHeader +| String +|=== diff --git a/docs/modules/ROOT/pages/OstRedemptionFlow.adoc b/docs/modules/ROOT/pages/OstRedemptionFlow.adoc new file mode 100644 index 0000000..a1158d2 --- /dev/null +++ b/docs/modules/ROOT/pages/OstRedemptionFlow.adoc @@ -0,0 +1,65 @@ += OstRedemption Flow + +== Introduction + +OstRedemption component is a pre-built UI component available exclusively in `ost-wallet-sdk-react-native` SDK. +It consist two pages - one displaying redeemable product list and another displaying product details and redemption options. +It can be used by end-users to integrate redemption flow into their app. + +____ +*IMPORTANT:* This feature requires application to use https://reactnavigation.org/docs/en/getting-started.html[React Navigation] package. +____ + +== Usage + +=== Create Redemption Flow stack navigation + +[source,js] +---- +import {OstRedeemableSkus, OstRedeemableSkuDetails } from '@ostdotcom/ost-wallet-sdk-react-native'; + +let redemptionStack = createStackNavigator( + { + RedeemableSkusScreen: OstRedeemableSkus, + RedeemableSkuDetails: OstRedeemableSkuDetails + } +); +---- + +=== Navigate to settings page + +`ostUserId` and `ostWalletUIWorkflowCallback` are mandetory parameters that need to be passed as params to the `RedeemableSkusScreen` screen. + +[source,js] +---- +const ostUserId = +const delegate = new OstWalletUIWorkflowCallback(ostUserId, {}) +this.props.navigation.push("RedeemableSkusScreen", {'ostUserId': ostUserId , + 'ostWalletUIWorkflowCallback': delegate, + 'navTitle': 'My Store'}); +---- + +____ +*Note* + Developer needs to create a class extends from `OstWalletUIWorkflowCallback` and write logic to get passphrase prefix from their application server. +Please refer link:OstWalletUI.md#setup-your-passphrase-prefix-delegate[this] section for documentation. +____ + +== UI Customization + +Developer can customize Redemption flow by updating respective properties mentioned in image. +OstTheme config shown link:./configs/ost-sdk-theme-config.js[here] + +image::images/redemptionFlow.png[copy-framework-file] + +== Redemption Content + +Developer can make various modifications in redemption flow component. +To modify contet, xref:./OstRedemptionConfig.adoc[refer here]. + +[source,js] +---- +import ost_sdk_redemption_config from "../../theme/ostsdk/ost-sdk-redemption-config"; +import { OstRedemableCustomConfig } from '@ostdotcom/ost-wallet-sdk-react-native'; + + OstRedemableCustomConfig.setConfig(ost_sdk_redemption_config); +---- diff --git a/docs/modules/ROOT/pages/OstTransactionConfig.adoc b/docs/modules/ROOT/pages/OstTransactionConfig.adoc new file mode 100644 index 0000000..a3687b8 --- /dev/null +++ b/docs/modules/ROOT/pages/OstTransactionConfig.adoc @@ -0,0 +1,46 @@ += OstTransaction Config + +== Introduction + +App developers can configure session `expiration_time` and `spending_limit` while executing transaction. +To configure the session creation parameters (session buckets), provide the sdk with JSON object. +The default configuration can be found link:../js/TransactionHelper/ost-transaction-config.json[here]. + +== Configuration Data Structure + +Here is the small sample json representation of the configuration. + +[source,js] +---- +{ + "session_buckets": [ + { + expiration_time: 60*60*24*30*2, //2 months + spending_limit: '10' + }, + { + expiration_time: 60*60*24*30, //1 months + spending_limit: '50' + }, + { + expiration_time: 60*60*24, //24 hours + spending_limit: '100' + }, + { + expiration_time: 60*60*1, //1 hour + spending_limit: '1000' + } + ] +} +---- + +In the above example: + +* The first-level key `session_buckets` corresponds to list of buckets for creating session. +The bucket selection is depends on `spending_limit`. +* The second-level keys + ** `expiration_time` : corresponds to expiry time of session. + ** `spending_limit` : corresponds to spending limit of session. + +Above configuration allows user to execute transction of spending limit `1000`. +SDK throws error, if user makes transaction above `1000`. diff --git a/docs/modules/ROOT/pages/OstTransactionHelper.adoc b/docs/modules/ROOT/pages/OstTransactionHelper.adoc new file mode 100644 index 0000000..e60c1a2 --- /dev/null +++ b/docs/modules/ROOT/pages/OstTransactionHelper.adoc @@ -0,0 +1,94 @@ += Ost Transaction Helper + +== Introduction + +Developer can call functions of transaction helper to execute transaction and setting up config for transaction. + +== Configuration + +App developers can configure session `expiration_time` and `spending_limit` while executing transaction. +To configure the session creation parameters (session buckets), the sdk needs to be provided with JSON object. +The default configuration can be found link:../js/TransactionHelper/ost-transaction-config.json[here]. + +=== Configuration Data Structure + +Here is the small sample json representation of the configuration. + +[source,js] +---- +{ + "session_buckets": [ + { + expiration_time: 60*60*24*30*2, //2 months + spending_limit: '10' + }, + { + expiration_time: 60*60*24*30, //1 months + spending_limit: '50' + }, + { + expiration_time: 60*60*24, //24 hours + spending_limit: '100' + }, + { + expiration_time: 60*60*1, //1 hour + spending_limit: '1000' + } + ] +} +---- + +In the above example: + +* The first-level key `session_buckets` corresponds to list of buckets for creating session. +The bucket selection is depends on `spending_limit`. +* The second-level keys + ** `expiration_time` : corresponds to expiry time of session. + ** `spending_limit` : corresponds to spending limit of session. + +Above configuration allows user to execute transction of spending limit `1000`. +SDK throws error, if user makes transaction above `1000`. + +=== Set Transaction Config + +Developer can set list of buckets for creating session. +For details, Please refer xref:./OstTransactionConfig.adoc[this] + +[source,js] +---- +import {OstTransactionHelper} from "@ostdotcom/ost-wallet-sdk-react-native/js/index" + +OstTransactionHelper.setTxConfig(ost-tx-config); +---- + +== Execute Direct Transfer + +Execute direct transfer can be performed by calling + +____ +*Note* + Developer needs to create a class extends from OstWalletUIWorkflowCallback and write logic to get passphrase prefix from their application server. +Please refer xref:./OstWalletUI.adoc[this] section for documentation. +____ + +[source,js] +---- +import {OstTransactionHelper} from "@ostdotcom/ost-wallet-sdk-react-native/js/index" + +const ostUserId = +const txMeta = {"type": "user_to_user", "name": "Tokens sent", "details": "Sending tokens vis direct transafer"}; +const workflowCallback = new OstWalletUIWorkflowCallback() + +let uuid = OstTransactionHelper.executeDirectTransfer(ostUserId, [tokenValue], [token_holder_address], txMeta, workflowCallback); + +OstWalletSdkUI.subscribe(uuid, OstWalletSdkUI.EVENTS.flowComplete, (workflowContext, contextEntity) => { + //functionality for transaction success +}); +OstWalletSdkUI.subscribe(uuid, OstWalletSdkUI.EVENTS.flowInterrupt, (workflowContext, ostError) => { + //functionality for transaction failed +}); +OstWalletSdkUI.subscribe(uuid, OstWalletSdkUI.EVENTS.requestAcknowledged, (workflowContext, contextEntity) => { + //functionality for transaction ack. +}); +---- + +New session will be created with appropriate bucket, if sdk won't get any active session for given spending limit. diff --git a/docs/modules/ROOT/pages/OstWalletSdkGetMethods.adoc b/docs/modules/ROOT/pages/OstWalletSdkGetMethods.adoc new file mode 100644 index 0000000..2d4c2db --- /dev/null +++ b/docs/modules/ROOT/pages/OstWalletSdkGetMethods.adoc @@ -0,0 +1,395 @@ += OST Wallet React Native SDK Getter Methods + +== Table of Contents + +* <> +* <> + ** <> + ** <> +* <> + ** <> + ** <> +* <> + ** <> + ** <> +* <> + ** <> +* <> + ** <> + ** <> +* <> + ** <> + ** <> + +++++++++++++ + +== Before We Begin + +* App must link:../README.md#initializing-the-sdk[initialize] the SDK _*before*_ initiating getter methods. +* We recommend using these methods _after_ link:../README.md#setupdevice[setupDevice] workflow has been performed. +* The getter methods provide the data as available with the device. + ** The methods may return `null` if the data is not available. +* These methods are _synchronous_ in the native SDK. +Because of react-native's bridge they behave _asynchronous_ in the react-native SDK. + ** These methods do not make any API calls. + +++++++++++++ + +== Get Token + +Method to get token information. + +____ +`getToken` method will return partial data if device has not been registered. +____ + +++++++++++++ + +.Usage +[source,js] +---- + /* + Please update tokenId as per your needs. + Since this tokenId does not belong to your economy, you may get an error if you do not change it. + */ + let tokenId = '1129'; + + /** + * Get token object for provided userId + * @param {String} tokenId - Ost Token id + * @param {function} callback - Gets token object if present else nil + * @callback params {Object} token entity. Returns null if information is not available with device. + * @public + */ + OstWalletSdk.getToken(tokenId, (tokenEntity) => { + console.log("tokenEntity", tokenEntity); + }); +---- + +++++++++++++ + +.Sample Response + +Please refer to the https://dev.ost.com/platform/docs/api/#token[Token Object] for a detailed description. + +[source,json] +---- +{ + "updated_timestamp": 1560167796, + "auxiliary_chains": [ + { + "organization": { + "owner": "0x8986922410e5d8cf43cfc94c1b51dcf8dfdf7637", + "contract": "0xb8e3fcfb5dac714e40b63489f4f393c7073fdbb3" + }, + "company_uuids": [ + "d6bf0061-a32d-48af-a29b-013260a947f3" + ], + "company_token_holders": [ + "0x93f08d0c5d7bc28cc117681b3b23f8501a09e786" + ], + "utility_branded_token": "0xc50e3fd492a9a99a964f7aff8d755075d0732ff0", + "chain_id": 197 + } + ], + "origin_chain": { + "stakers": [ + "0x8986922410e5d8cf43cfc94c1b51dcf8dfdf7637" + ], + "organization": { + "owner": "0x8986922410e5d8cf43cfc94c1b51dcf8dfdf7637", + "contract": "0x0260a404804b1d7cf6fa678fb5d8441495cfff1b" + }, + "branded_token": "0x18cbeae2f1785abf68c9984f9186a29ed062c3ca", + "chain_id": 3 + }, + "decimals": 6, + "total_supply": "500000000000", + "conversion_factor": 10, + "base_token": "USDC", + "symbol": "SC1", + "name": "STC1", + "id": 1129 +} +---- + +++++++++++++ + +== Get User + +Method to get user information. + +____ +`getUser` method will return partial data if device has not been registered. +____ + +++++++++++++ + +.Usage +[source,js] +---- + /* + Please update userId as per your needs. + Since this userId does not belong to your economy, you will get an error if you do not change it. + */ + let userId = "71c59448-ff77-484c-99d8-abea8a419836"; + + /** + * Get user object for provided userId + * @param {String} userId - Ost User id + * @param {function} callback - Gets object if present else nil + * @callback params {Object}user + * @public + */ + OstWalletSdk.getUser(userId, (userEntity)=>{ + console.log( userEntity ); + }); +---- + +++++++++++++ + +.Sample Response +[source,json] +---- +{ + "updated_timestamp": 1566832473, + "status": "ACTIVATED", + "type": "user", + "recovery_owner_address": "0x0a64dc924d32a569b1d0885acfc34832e1444944", + "recovery_address": "0x99c46a66621d6967cbd692e615ec36747d58fecb", + "device_manager_address": "0x55f379612796b863590d388ed509ae50de12a5d2", + "token_holder_address": "0xbf3df93b15c6933177237d9ed8400a2f41c8b8a9", + "token_id": 1129, + "id": "71c59448-ff77-484c-99d8-abea8a419836" +} +---- + +++++++++++++ + +== Get Current Device + +Method to get device entity. + +++++++++++++ + +.Usage +[source,js] +---- + /* + Please update userId as per your needs. + Since this userId does not belong to your economy, you may get an error if you do not change it. + */ + let userId = "71c59448-ff77-484c-99d8-abea8a419836"; + + /** + * Get current device object for provided userId + * @param {String} userId - Ost User id + * @param {function} callback - Gets current device object if present else nil + * @callback params {Object} device + * @public + */ + OstWalletSdk.getCurrentDeviceForUserId(userId, (device)=>{ + console.log( device ); + }); +---- + +++++++++++++ + +.Sample Response +[source,json] +---- +{ + "updated_timestamp": 1566832473, + "status": "AUTHORIZED", + "api_signer_address": "0x674d0fc0d044f085a87ed742ea778b55e298b429", + "linked_address": "0x73722b0c0a6b6418893737e0ca33dd567e33f6aa", + "address": "0x8d92cf567191f07e5c1b487ef422ff684ddf5dd3", + "user_id": "71c59448-ff77-484c-99d8-abea8a419836" +} +---- + +++++++++++++ + +== Get Biometric Preference + +Method to get biometric preference of the user. + +++++++++++++ + +.Usage +[source,js] +---- + /* + Please update userId as per your needs. + Since this userId does not belong to your economy, you may get an error if you do not change it. + */ + let userId = "71c59448-ff77-484c-99d8-abea8a419836"; + + /** + * Get biometric preference for user + * + * @param userId - Ost User id + * @param callback - Gets biometric preference boolean value + */ + OstWalletSdk.isBiometricEnabled(userId, (status) => { + console.log("isBiometricEnabled", status ); + // logs true or false. + }); +---- + +++++++++++++ + +== Get Active Sessions + +Method to get active sessions available with device. + +++++++++++++ + +.Usage +[source,js] +---- + /* + Please update userId and minimumSpendingLimitInWei as per your needs. + Since this userId does not belong to your economy, you may get an error if you do not change it. + */ + let userId = "71c59448-ff77-484c-99d8-abea8a419836"; + let minimumSpendingLimitInWei = "1000000"; + + /** + * Get user object for provided userId + * @param {String} userId - Ost User id + * @param {String} minimumSpendingLimitInWei - optional parameter, defaults to zero. + * @param {function} callback - Gets array of current device sessions. + * @callback params {Array} array of sessions + * @public + */ + OstWalletSdk.getActiveSessionsForUserId(userId, minimumSpendingLimitInWei, (activeSessions)=>{ + console.log(activeSessions); + }); + + + // Optionally, getActiveSessionsForUserId method can also + // be invoked without specifying minimumSpendingLimitInWei. + OstWalletSdk.getActiveSessionsForUserId(userId,(activeSessions)=>{ + console.log(activeSessions); + }); +---- + +++++++++++++ + +.Sample Response +[source,json] +---- +[ + { + "updated_timestamp": 1566832473, + "status": "AUTHORIZED", + "nonce": 2, + "spending_limit": "1000000000000000000", + "approx_expiration_timestamp": 1566922426, + "expiration_height": 3607838, + "address": "0x3171bce99d00812b77aa216ed544ab35fc8b6fb1", + "user_id": "71c59448-ff77-484c-99d8-abea8a419836" + }, + { + "updated_timestamp": 1566832473, + "status": "AUTHORIZED", + "nonce": 2, + "spending_limit": "1000000000000000000", + "approx_expiration_timestamp": 1566922426, + "expiration_height": 3607838, + "address": "0x816324ed539b62652a247ce5c1f1962f6de13e14", + "user_id": "71c59448-ff77-484c-99d8-abea8a419836" + }, + { + "updated_timestamp": 1566832473, + "status": "AUTHORIZED", + "nonce": 3, + "spending_limit": "1000000000000000000", + "approx_expiration_timestamp": 1566922426, + "expiration_height": 3607838, + "address": "0x95b3fcb5aa3930a9bc42da171b8733a3a869955f", + "user_id": "71c59448-ff77-484c-99d8-abea8a419836" + }, + { + "updated_timestamp": 1566832473, + "status": "AUTHORIZED", + "nonce": 3, + "spending_limit": "1000000000000000000", + "approx_expiration_timestamp": 1566922426, + "expiration_height": 3607838, + "address": "0xe57b68fc8aca57d9488d1607df628a4076571eda", + "user_id": "71c59448-ff77-484c-99d8-abea8a419836" + }, + { + "updated_timestamp": 1566832473, + "status": "AUTHORIZED", + "nonce": 2, + "spending_limit": "1000000000000000000", + "approx_expiration_timestamp": 1566922426, + "expiration_height": 3607838, + "address": "0x459712cb13efd12ade7ff3a5fd4641f5c21904c9", + "user_id": "71c59448-ff77-484c-99d8-abea8a419836" + } +] +---- + +++++++++++++ + +== QR Code for Authorizing Device + +Method to generate QR code that can be scanned by an *authorized* device. +Scanning this QR code with an authorized mobile device will result in this device (from where the QR code has been generated) being authorized. + +____ +App should use this method only when the current device status is `REGISTERED`. +____ + +++++++++++++ + +.Usage +[source,js] +---- + /* + Please update userId and minimumSpendingLimitInWei as per your needs. + Since this userId does not belong to your economy, you may get an error if you do not change it. + */ + let userId = "71c59448-ff77-484c-99d8-abea8a419836"; + + /** + * Get device QR code + * @param {String} userId - Ost User id + * @param {function} successCallback - returns image as base64 string. + * @param {function} errorCallback. + * @public + */ + OstWalletSdk.getAddDeviceQRCode( userId , (base64Image) => { + console.log(base64Image); + // Assuming this method is called from Component, + // let's update the component's state to display the image. + this.setState({ + qrCode: base64Image + }); + }, (error) => { + + }); +---- + +++++++++++++ + +.Sample Render Method +[source,jsx] +---- + render() { + // Assuming that callback will set 'qrCode' attribute in component's state. + if ( this.state.qrCode ) { + return ( + + ); + } + return null; + } +---- diff --git a/docs/modules/ROOT/pages/OstWalletSettings.adoc b/docs/modules/ROOT/pages/OstWalletSettings.adoc new file mode 100644 index 0000000..45115b0 --- /dev/null +++ b/docs/modules/ROOT/pages/OstWalletSettings.adoc @@ -0,0 +1,78 @@ += OstWallet Settings + +== Introduction + +OstWallet Settings is a pre-built UI Component available exclusively available in `ost-wallet-sdk-react-native` Sdk. +It is a wallet settings page that can be used by end-users to perfrom different wallet operations. + +____ +*IMPORTANT:* This feature requires application to use https://reactnavigation.org/docs/en/getting-started.html[React Navigation] package. +____ + +OstWalletSettings supports 13 workflows: + +* Activate User +* Wallet Details +* Initialize Recovery +* Add Session +* Reset a User's PIN +* Get Mnemonic Phrase +* Authorize device using mnemonics +* Abort Device Recovery +* Revoke Device +* Scan QR Code to add another device +* Get Current Device QR code +* Enable Biometrics +* Disable Biometrics + +== Usage + +=== Create wallet settings stack navigation + +[source,js] +---- +import {OstWalletSettingsComponent} from '@ostdotcom/ost-wallet-sdk-react-native'; + +let settingsStack = createStackNavigator( + { + "WalletSettingScreen": OstWalletSettingsComponent + } +); +---- + +=== Naviagte to settings page + +`ostUserId` and `ostWalletUIWorkflowCallback` are mandetory parameters that need to be passed as params to the `WalletSettingScreen` screen. + +[source,js] +---- +const ostUserId = +const delegate = new OstWalletUIWorkflowCallback(ostUserId, {}) +this.props.navigation.push("WalletSettingScreen", {'ostUserId': ostUserId, 'ostWalletUIWorkflowCallback': delegate}); +---- + +____ +*Note* + Developer needs to create a class extends from `OstWalletUIWorkflowCallback` and write logic to get passphrase prefix from their application server. +Please refer link:OstWalletUI.md#setup-your-passphrase-prefix-delegate[this] section for documentation. +____ + +== UI Customization + +Developer can customize wallet settings by updating respective properties mentioned in image. +OstTheme config shown link:./configs/ost-sdk-theme-config.js[here] + +image:images/wallet_settings.png[copy-framework-file] image:images/wallet_details.png[copy-framework-file] + +== Settings Content + +Developer can modify `header` and `description` of settings options. +To modify contet, xref:./OstWalletSettingsConfig.adoc[refer here]. + +[source,js] +---- +import {OstWalletSettings} from "@ostdotcom/ost-wallet-sdk-react-native/js/index"; + +let settingsContentConfig = {} + +OstWalletSettings.setMasterConfig(settingsContentConfig) +---- diff --git a/docs/modules/ROOT/pages/OstWalletSettingsConfig.adoc b/docs/modules/ROOT/pages/OstWalletSettingsConfig.adoc new file mode 100644 index 0000000..f441cb3 --- /dev/null +++ b/docs/modules/ROOT/pages/OstWalletSettingsConfig.adoc @@ -0,0 +1,121 @@ += OstWallet Settings Config + +== Introduction + +App developers can configure the text shown on settings page. + +To configure the content, the sdk needs to be provided with https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/JSON[JSON object]. + +The default configuration can be found link:../js/WalletSettings/ost-wallet-settings-config.json[here]. + +== Dictionary Data Structure + +Here is the small sample json representation of the configuration. + +[source,json] +---- +{ + "item_display_order": [ + "activate_user", + ], + "item_configs": { + "activate_user": { + "content_config": { + "heading": "Activate User", + "description": "User is not activated yet." + }, + "config": { + "spending_limit": "0", + "expiration_time": 0 + } + } + } +} +---- + +In the above example: + +* The first-level key `item_display_order` corresponds to sequence of allowed workflows. +* The first-level key `item_configs` corresponds to config for workflows. +* The second-level key `activate_user` corresponds to activate user workflow. +* The third-level key `content_config` corresponds to `heading` and `description` of workflows. +* The third-level key `config` corresponds to respective config for workflows. + +== Supported Workflows + +OstWalletSettings supports 13 workflows + +|=== +| Configuration Keys | Workflows + +| activate_user +| Activate User + +| wallet_details +| Wallet Details + +| recover_device +| Initialize Recovery + +| add_session +| Add Session + +| reset_pin +| Reset a User's PIN + +| show_mnemonics +| Get Mnemonic Phrase + +| authorize_device_with_mnemonics +| Authorize device using mnemonics + +| abort_recovery +| Abort Device Recovery + +| revoke_device +| Revoke Device + +| add_another_device +| Scan QR Code to add another device + +| show_device_qr_code +| Get current Device QR code + +| enable_biometrics +| Use biometrics to authorize new Sessions and to confirm high value transactions. + +| disable_biometrics +| Turn off biometrics and use PIN to authorize new Sessions and to confirm high value transactions. +|=== + +* All workflows have `content_config`. +* `config` varies workflow to workflow. + +== Workflow Config + +Some workflows requires additional data. +It can be passed to workflow by setting it in `config`. + +|=== +| Workflows | Config Keys | Config Type + +| activate_user +| - spending_limit +| String + +| +| - expiration_time +| Number + +| wallet_details +| - ost_view_endpoint +| String + +| add_session +| - spending_limit +| String + +| +| - expiration_time +| Number +|=== diff --git a/docs/modules/ROOT/pages/OstWalletUI.md.adoc b/docs/modules/ROOT/pages/OstWalletUI.md.adoc new file mode 100644 index 0000000..3cf08bd --- /dev/null +++ b/docs/modules/ROOT/pages/OstWalletUI.md.adoc @@ -0,0 +1,986 @@ += OST Wallet React Native SDK UI + +== Introduction + +For quick and easy integration with SDK, developers can use built-in user interface components which are configurable and support content and theme customization. +All OstWalletSdkUI workflows return `workflow-id`. +The application can subscribe to the events of the workflow using the `workflow-id`. + +== Setup + +`OstWalletSdkUI` is packaged along with OstWalletSdk. +There are no additional steps for using `OstWalletSdkUI`. +To setup OstWalletSdk, please refer to link:../README.md#installing-react-native-sdk[setup]. + +== Before We Begin + +* App must link:../README.md#initializing-the-sdk[initialize] the sdk _*before*_ initiating any UI workflows. +* App must perform link:../README.md#setupdevice[setupDevice] workflow _*before*_ initiating any UI workflows. + +== OstWalletSdkUI SDK APIs + +To use OstWalletSdkUI + +---- +import {OstWalletSdkUI} from '@ostdotcom/ost-wallet-sdk-react-native'; +---- + +=== Set Theme Config + +Theme for OstWalletSdkUI can be initialized by calling `setThemeConfig` API which setup OstWalletSdkUI theme config. +To define custom theme config, please refer to https://github.com/ostdotcom/ost-wallet-sdk-android/blob/release-2.3/documentation/ThemeConfig.md[Theme Config Android]/https://github.com/ostdotcom/ost-wallet-sdk-ios/blob/release-2.3/documentation/ThemeConfig.md[Theme Config iOS] documentation. + +[source,js] +---- + // Define the content config + const theme_config = { + "nav_bar_logo_image": { + "asset_name": "YOUR_LOGO_ASSET_NAME" + } + }; + + /** + * Set theme config for UI + * config: Config to use for UI + */ + OstWalletSdkUI.setThemeConfig(theme_config); +---- + +____ +* In the above example, `asset_name` is name of asset which is present in the respective assets folder for iOS/android. +____ + +=== Set Content Config + +Content for OstWalletSdkUI can be initialized by calling `setContentConfig` API which set-up OstWalletSdkUI content config. +To define custom content config, please refer to https://github.com/ostdotcom/ost-wallet-sdk-android/blob/release-2.3/documentation/ContentConfig.md[Content Config Android]/https://github.com/ostdotcom/ost-wallet-sdk-ios/blob/release-2.3/documentation/ContentConfig.md[Content Config iOS] documentation. + +[source,js] +---- + // Please update terms_and_condition.url as per your needs. + const content_config = { + "activate_user": { + "create_pin": { + "placeholders": { + "terms_and_condition": { + "url": "https://YOUR-WEB-SITE.com/terms-page" + } + } + }, + "confirm_pin": { + "placeholders": { + "terms_and_condition": { + "url": "https://YOUR-WEB-SITE.com/terms-page" + } + } + } + } + }; + + /** + * Set content config for UI + * config: Config to use for UI + */ + OstWalletSdkUI.setContentConfig(content_config); +---- + +=== Set Loader Manager + +Application loader for OstWalletUI can be initialized by calling `setLoaderManager` API. +This API is available in native SDK. ++ + Custom loader is supported from OstWalletSdk-native version Android v``2.3.6`` Or iOS v``2.3.5`` + Please, verify OstWalletSdk version in `Cartfile`. ++ + Custom loader needs to be written in native code (java, swift/Objective-C). ++ Sample code for custom loader is available in respective platform directory. +For https://github.com/ostdotcom/ost-wallet-sdk-ios/blob/release-2.3/Samples/CustomLoader/OstMockCustomLoader.md[iOS] and https://github.com/ostdotcom/ost-wallet-sdk-android/blob/develop/Samples/customloader/OstCustomLoader.md[Android] + +=== Setup your Passphrase Prefix Delegate + +`Passphrase Prefix` is a salt provided by your application that assists in generation of User's recovery key using user's PIN. +This salt should be _unique_ for each user, is immutable and needs to be associated with the user. +The salt should not be stored in memory or on deivce unencrypted. +When the UI workflow need's to ask for user's PIN, delegate's getPassphrase method is invoked. + +The delegate must be derived from `OstWalletUIWorkflowCallback` class. + +Here is an example: + +[source,javascript] +---- +import { OstWalletUIWorkflowCallback } from '@ostdotcom/ost-wallet-sdk-react-native'; +class UserPassphrasePrefixDelegate extends OstWalletUIWorkflowCallback { + constructor() { + super(); + } + + getPassphrase(userId, ostWorkflowContext, OstPassphrasePrefixAccept) { + let fetchPromise = new Promise((resolve,reject) => { + //Write code here to validate userId. + //If it is not the same as that of the logged-in user, reject the promise. + + //Write code here to fetch the salt from your server. + //Read the passphrasePrefix from response and resolve the Promise. + }); + fetchPromise + .then((passphrasePrefix) => { + OstPassphrasePrefixAccept.setPassphrase(passphrasePrefix, userId, (error) => { + console.warn(error); + }); + }) + .catch((err) => { + // Cancel the workflow. + OstPassphrasePrefixAccept.cancelFlow(); + }); + } + + /** + * Optional Callback Implementation + * -------------------------------- + * + * Application can also define and use following callback methods: + * - requestAcknowledged(ostWorkflowContext , ostContextEntity ) + * - flowComplete(ostWorkflowContext , ostContextEntity ) + * - flowInterrupt(ostWorkflowContext , ostError) + * + * Note: + * These methods can be helpful for debugging. + * Defining these methods does NOT impact ui workflow event subscription in any way. + * If application subscribes to events and also defines these callbacks, both shall be invoked. + */ + + requestAcknowledged(ostWorkflowContext , ostContextEntity ) { + console.log("Received requestAcknowledged callback"); + + let contextWorkflowId = ostWorkflowContext.WORKFLOW_ID; + let workflowType = ostWorkflowContext.WORKFLOW_TYPE; + let entityType = ostContextEntity.entityType; + let entityData = ostContextEntity.entity; + + console.log("- Workflow Id:", contextWorkflowId); + console.log("- Workflow Type:", workflowType); + console.log("- OstContextEntity type:", entityType) + console.log("- OstContextEntity entityData:", entityData); + } + + flowComplete(ostWorkflowContext , ostContextEntity ) { + console.log("Received flowComplete callback"); + + let contextWorkflowId = ostWorkflowContext.WORKFLOW_ID; + let workflowType = ostWorkflowContext.WORKFLOW_TYPE; + let entityType = ostContextEntity.entityType; + let entityData = ostContextEntity.entity; + + console.log("- Workflow Id:", contextWorkflowId); + console.log("- Workflow Type:", workflowType); + console.log("- OstContextEntity type:", entityType) + console.log("- OstContextEntity entityData:", entityData); + } + + flowInterrupt(ostWorkflowContext , ostError) { + console.log("Received flowInterrupt callback"); + + let contextWorkflowId = ostWorkflowContext.WORKFLOW_ID; + let workflowType = ostWorkflowContext.WORKFLOW_TYPE; + let errorData = ostError.error; + let errorCode = ostError.getErrorCode(); + + // If you would like to reach out to Ost Devs for support, + // we request you to collect internalErrorCode + let internalErrorCode = ostError.getInternalErrorCode(); + let isApiError = ostError.isApiError(); + + console.log("- Workflow Id:", contextWorkflowId); + console.log("- Workflow Type:", workflowType); + console.log("- Error"); + console.log(" - Error Code:", errorCode); + console.log(" - Is Api Error:", isApiError); + console.log(" - Sdk Internal Error Code", internalErrorCode); + console.log(" - error data", errorData); + + if ( isApiError && ostError.isApiSignerUnauthorized() ) { + console.log("- This device has either been revoked or not yet registered."); + } else if ("WORKFLOW_CANCELED" === errorCode.toUpperCase() ) { + console.log("- This error can be ignored. The workflow has been canceled by the user or application"); + } + } +} +export default UserPassphrasePrefixDelegate; +---- + +=== Ost Wallet Settings + +OstWallet Settings is a pre-built UI Component available exclusively available in `ost-wallet-sdk-react-native` Sdk. +It is a wallet settings page that can be used by end-users to perfrom different wallet operations(Ost Wallet UI Workflows). +For details xref:./OstWalletSettings.adoc[check here] + +____ +*Note* + `OstWalletSettings` is available from `ost-wallet-sdk-react-native` SKD version v2.3.12-beta.1 +____ + +=== Ost Wallet UI Workflows + +==== Activate User + +User activation refers to the deployment of smart-contracts that form the user's token wallet. +An activated user can engage with a token. + +[source,javascript] +---- + +let uiCallback = new UserPassphrasePrefixDelegate() + +/** +* Activate user +* @param {String} userId - Ost User id +* @param {String} expiresAfterInSecs - session key expiry time. +* @param {String} spendingLimit - spending limit once in a transaction of session +* @param {OstWalletUIWorkflowCallback} uiCallback - callback implementation instances for application communication +* @public +*/ +let workflowId = OstWalletSdkUI.activateUser( + userId, + expiresAfterInSecs, + spendingLimit, + uiCallback +); + +// Subscribe to events +OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.requestAcknowledged, () => { + // User is being activated. At this point, user can neither receive or send tokens. +}); + +OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowComplete, (ostWorkflowContext , ostContextEntity) => { + // Show success message to user. + // User has been activated. User can now start receiving tokens. +}); + +OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowInterrupt, (ostWorkflowContext , ostError) => { + // Show error to user. + // An error occoured during the workflow. The user has NOT been activated. +}); +---- + +==== Add Session + +A session is a period of time during which a sessionKey is authorized to sign transactions under a pre-set limit per transaction on behalf of the user. +The device manager, which controls the tokens, authorizes sessions. + +* *By Calling function* + + +[source,js] +---- + +let uiCallback = new UserPassphrasePrefixDelegate() + +/** + * Add user session + * @param {String} userId - Ost User id + * @param {String} expiresAfterInSecs - session key expiry time. + * @param {String} spendingLimit - spending limit once in a transaction of session + * @param {OstWalletUIWorkflowCallback} uiCallback - callback implementation instances for application communication + * @public + */ +let workflowId = OstWalletSdkUI.addSession( + userId, + expiresAfterInSecs, + spendingLimit, + uiCallback +) + +// Subscribe to events +OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.requestAcknowledged, () => { + // Session is being added. +}); + +OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowComplete, (ostWorkflowContext , ostContextEntity) => { + // Show success message to user. + // Session has been added. +}); + +OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowInterrupt, (ostWorkflowContext , ostError) => { + // Show error to user. + // An error occoured during the workflow. The Session has NOT been added. +}); +---- + +* ++++++By scanning QR-Code ++++++ + + +QR Code Sample + +---- +as|2.0.0|2a421359d02132e8161cda9518aeaa62647b648e|5369b4d7e0e53e1159d6379b989a8429a7b2dd59|1|1583308559|4d40c46a7302974134a67ce77bdfae0e1f78ee518e87b6cda861ffc5847dfaca11a653651c6cdfadf0224574f6f07e1a78aabacdfed66d8c78e1fb2c9bc750161c +---- + +[source,js] +---- + +let uiCallback = new UserPassphrasePrefixDelegate() + +/** + * Add user session + * @param {String} userId - Ost User id + * @param {OstWalletUIWorkflowCallback} uiCallback - callback implementation instances for application communication + * @public + */ +let workflowId = OstWalletSdkUI.scanQRCodeToAuthorizeSession( + userId, + uiCallback +) + +// Subscribe to events +OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.requestAcknowledged, () => { + // Session is being added. +}); + +OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowComplete, (ostWorkflowContext , ostContextEntity) => { + // Show success message to user. + // Session has been added. +}); + +OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowInterrupt, (ostWorkflowContext , ostError) => { + // Show error to user. + // An error occoured during the workflow. The Session has NOT been added. +}); +---- + +* ++++++With QR Code Payload ++++++ + + +[source,js] +---- + +let uiCallback = new UserPassphrasePrefixDelegate() +let payload = "as|2.0.0|2a421359d02132e8161cda9518aeaa62647b648e|5369b4d7e0e53e1159d6379b989a8429a7b2dd59|1|1583308559|4d40c46a7302974134a67ce77bdfae0e1f78ee518e87b6cda861ffc5847dfaca11a653651c6cdfadf0224574f6f07e1a78aabacdfed66d8c78e1fb2c9bc750161c" +/** + * Authorize browser session with QR code payload + * @param {String} userId - Ost User id + * @param {String} qrPayload - QR-Code payload + * @param {OstWalletUIWorkflowCallback} uiCallback - callback implementation instances for application communication + * @return {*|number} + */ +let workflowId = OstWalletSdkUI.authorizeSessionWithQRPayload( + userId, + payload, + uiCallback +) + +// Subscribe to events +OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.requestAcknowledged, () => { + // Session is being added. +}); + +OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowComplete, (ostWorkflowContext , ostContextEntity) => { + // Show success message to user. + // Session has been added. +}); + +OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowInterrupt, (ostWorkflowContext , ostError) => { + // Show error to user. + // An error occoured during the workflow. The Session has NOT been added. +}); +---- + +==== Get Mnemonic Phrase + +The mnemonic phrase represents a human-readable way to authorize a new device. +This phrase is 12 words long. + +[source,js] +---- +let uiCallback = new UserPassphrasePrefixDelegate() + +/** + * Get device mnemonics + * @param {String} userId - Ost User id + * @param {OstWalletUIWorkflowCallback} uiCallback - callback implementation instances for application communication + * @public + */ +let workflowId = OstWalletSdkUI.getDeviceMnemonics( + userId, + uiCallback +) + +// Subscribe to events +OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowComplete, (ostWorkflowContext , ostContextEntity) => { + // Show success message to user. + // User has seen the mnemonics +}); + +OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowInterrupt, (ostWorkflowContext , ostError) => { + // Show error to user. + // An error occoured during the workflow. +}); +---- + +==== Reset a User's PIN + +The user's PIN is set when activating the user. +This method supports re-setting a PIN and re-creating the recoveryOwner as part of that. + +[source,js] +---- + +let uiCallback = new UserPassphrasePrefixDelegate() + +/** + * Reset pin + * + * @param {String} userId - Ost User id + * @param {OstWalletUIWorkflowCallback} uiCallback - callback implementation instances for application communication + */ +let workflowId = OstWalletSdkUI.resetPin( + userId, + uiCallback +) + +// Subscribe to events +OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.requestAcknowledged, () => { + // Pin is being reset. +}); + +OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowComplete, (ostWorkflowContext , ostContextEntity) => { + // Show success message to user. + // Workflow completed successfully. +}); + +OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowInterrupt, (ostWorkflowContext , ostError) => { + // Show error to user. + // An error occoured during the workflow. +}); +---- + +==== Initiate Recovery + +A user can control their tokens using their authorized device(s). +If the user loses their authorized device, she can recover access to their tokens by authorizing a new device via the recovery process. + +If application set `recoverDeviceAddress` then OstWalletUI ask for `pin` to initiate device recovery. +Else it displays authorized device list for given `userId` to select device from. + +[source,javascript] +---- + +let uiCallback = new UserPassphrasePrefixDelegate(); + +/** +* Initiate device recovery +* @param {String} userId - Ost User id +* @param {String} recoverDeviceAddress - Device address which wants to recover +* @param {OstWalletUIWorkflowCallback} uiCallback - callback implementation instances for application communication +* @public +*/ +let workflowId = OstWalletSdkUI.initiateDeviceRecovery( + userId, + recoverDeviceAddress, + uiCallback +) + +// Subscribe to events +OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.requestAcknowledged, () => { + // Device recovery has been initiated. + // The device will be recovered after 12 hours. +}); + +OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowComplete, (ostWorkflowContext , ostContextEntity) => { + // Show success message to user. + // Device recovery has been initiated. + // The device will be recovered after 12 hours. +}); + +OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowInterrupt, (ostWorkflowContext , ostError) => { + // Show error to user. + // An error occoured during the workflow. +}); +---- + +____ +`recoverDeviceAddress` can be `null`. ++ If you have your own UI to select the device to revoke, set `recoverDeviceAddress` to the selected device address. ++ When `null` is passed, the Sdk will ask user to choose the device using built-in device list UI. ++ +____ + +==== Abort Device Recovery + +To abort initiated device recovery. + +[source,javascript] +---- + + let uiCallback = new UserPassphrasePrefixDelegate(); + + /** + * Abort device recovery + * @param {String} userId - Ost User id + * @param {OstWalletUIWorkflowCallback} uiCallback - callback implementation instances for application communication + * @public + */ + OstWalletSdkUI.abortDeviceRecovery( + userId, + uiCallback + ) + + // Subscribe to events + OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.requestAcknowledged, () => { + // Request has been acknowledged by OST Platform. + }); + + OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowComplete, (ostWorkflowContext , ostContextEntity) => { + // Show success message to user. + // Device recovery has been aborted. + }); + + OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowInterrupt, (ostWorkflowContext , ostError) => { + // Show error to user. + // An error occoured during the workflow. + }); +---- + +==== Revoke Device + +To revoke device access. + +[source,js] +---- + + let uiCallback = new UserPassphrasePrefixDelegate(); + + /** + * Revoke device + * @param {String} userId - Ost User id + * @param {String} deviceAddressToRevoke - Device address which wants to recover + * @param {OstWalletUIWorkflowCallback} uiCallback - callback implementation instances for application communication + * @public + */ + let workflowId = OstWalletSdkUI.revokeDevice(userId, deviceAddressToRevoke, uiCallback ); + + // Subscribe to events + OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.requestAcknowledged, () => { + // Request has been acknowledged by OST Platform. + }); + + OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowComplete, (ostWorkflowContext , ostContextEntity) => { + // Show success message to user. + // Device has been revoked. + }); + + OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowInterrupt, (ostWorkflowContext , ostError) => { + // Show error to user. + // An error occoured during the workflow. + }); +---- + +____ +`deviceAddressToRevoke` can be `null`. ++ If you have your own UI to select the device to revoke, set `deviceAddressToRevoke` to the selected device address. ++ When `null` is passed, the Sdk will ask user to choose the device using built-in device list UI. ++ +____ + +==== Update Biometric Preference + +To enable or disable the biometric. + +[source,js] +---- + + let uiCallback = new UserPassphrasePrefixDelegate(); + let shouldEnable = true; + + /** + * Update biometric preference + * @param {String} userId - Ost User id + * @param {boolean} shouldEnable - pass true to enable biometic preference, false to disable. + * @param {OstWalletUIWorkflowCallback} uiCallback - callback implementation instances for application communication + * @public + */ + let workflowId = OstWalletSdkUI.updateBiometricPreference( userId, shouldEnable, uiCallback ); + + // Subscribe to events + OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowComplete, (ostWorkflowContext , ostContextEntity) => { + // Show success message to user. + // Preference has been updated. + }); + + OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowInterrupt, (ostWorkflowContext , ostError) => { + // Show error to user. + // An error occoured during the workflow. + }); +---- + +==== Authorize Current Device With Mnemonics + +To add a new device using 12 words recovery phrase. + +[source,js] +---- + + let uiCallback = new UserPassphrasePrefixDelegate(); + /** + * Authorize user device with mnemonics + * @param {String} userId - Ost User id + * @param {OstWalletWorkFlowCallback} workflow - callback implementation instances for application communication + * @public + */ + let workflowId = OstWalletSdkUI.authorizeCurrentDeviceWithMnemonics(userId, uiCallback); + + // Subscribe to events + OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.requestAcknowledged, () => { + // Request has been acknowledged by OST Platform. + }); + + OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowComplete, (ostWorkflowContext , ostContextEntity) => { + // Show success message to user. + // Device has been authorized. + }); + + OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowInterrupt, (ostWorkflowContext , ostError) => { + // Show error to user. + // An error occoured during the workflow. + }); +---- + +==== Get Add Device QR-Code + +To show QR-Code to scan from another authorized device + +[source,js] +---- + + let uiCallback = new UserPassphrasePrefixDelegate(); + + /** + * Get add device QR code + * + * @param {String} userId - Ost User id + * @param {OstWalletUIWorkflowCallback} uiCallback - callback implementation instances for application communication + * @public + */ + let workflowId = OstWalletSdkUI.getAddDeviceQRCode(userId, uiCallback); + + // Subscribe to events + OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.requestAcknowledged, () => { + // Current Device is being authorized. + }); + + OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowComplete, (ostWorkflowContext , ostContextEntity) => { + // Show success message to user. + // Current Device has been authorized. + }); + + OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowInterrupt, (ostWorkflowContext , ostError) => { + // Show error to user. + // An error occoured during the workflow. + }); +---- + +=== Scan QR-Code to Authorize Device + +To authorize device by scanning device QR-Code. + +QR-Code Sample: + +[source,json] +---- +{ + "dd":"AD", + "ddv":"1.1.0", + "d":{ + "da": "0x7701af46018fc57c443b63e839eb24872755a2f8" + } +} +---- + +* ++++++By scanning QR-Code ++++++ + + +[source,js] +---- + let uiCallback = new UserPassphrasePrefixDelegate(); + + /** + * Scan QR-Code to authorize device + * @param {String} userId - Ost User id + * @param {OstWalletUIWorkflowCallback} uiCallback - callback implementation instances for application communication + * @public + */ + let workflowId = OstWalletSdkUI.scanQRCodeToAuthorizeDevice(userId, uiCallback); + + // Subscribe to events + OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.requestAcknowledged, () => { + // Device is being authorized. + }); + + OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowComplete, (ostWorkflowContext , ostContextEntity) => { + // Show success message to user. + // Device has been authorized. + }); + + OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowInterrupt, (ostWorkflowContext , ostError) => { + // Show error to user. + // An error occoured during the workflow. + }); +---- + +* ++++++with QR Code payload ++++++ + Developer can pass QR code payload to authorize device. +QR code scanner view won't open if developer pass payload. + +[source,js] +---- + let uiCallback = new UserPassphrasePrefixDelegate(); + let payload = "{\"dd\":\"AD\",\"ddv\":\"1.1.0\",\"d\":{\"da\":\"0x7701af46018fc57c443b63e839eb24872755a2f8\"}}" + /** + * Authorize device with QR code payload + * @param {String} userId - Ost User id + * @param {String} qrPayload - QR-Code payload + * @param {OstWalletUIWorkflowCallback} uiCallback - callback implementation instances for application communication + * @return {*|number} + */ + let workflowId = OstWalletSdkUI.authorizeDeviceWithQRPayload(userId, payload, uiCallback); + + // Subscribe to events + OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.requestAcknowledged, () => { + // Device is being authorized. + }); + + OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowComplete, (ostWorkflowContext , ostContextEntity) => { + // Show success message to user. + // Device has been authorized. + }); + + OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowInterrupt, (ostWorkflowContext , ostError) => { + // Show error to user. + // An error occoured during the workflow. + }); +---- + +=== Execute Transaction + +* ++++++By Scanning QR-Code ++++++ + To execute transaction via device by scanning device QR-Code. + +QR-Code Sample: + +[source,json] +---- +{ + "dd":"TX", + "ddv":"1.1.0", + "d":{ + "rn":"direct transfer", + "ads":[ + "0x7701af46018fc57c443b63e839eb24872755a2f8", + "0xed09dc167a72d939ecf3d3854ad0978fb13a8fe9" + ], + "ams":[ + "1000000000000000000", + "1000000000000000000" + ], + "tid": 1140, + "o":{ + "cs":"USD", + "s": "$" + } + }, + "m":{ + "tn":"comment", + "tt":"user_to_user", + "td":"Thanks for comment" + } +} +---- + +[source,js] +---- + + let uiCallback = new UserPassphrasePrefixDelegate(); + + /** + * Scan QR-Code to execute transaction + * + * @param {String} userId - Ost User id + * @param {OstWalletUIWorkflowCallback} uiCallback - callback implementation instances for application communication + * @public + */ + let workflowId = OstWalletSdkUI.scanQRCodeToExecuteTransaction(userId, uiCallback); + + // Subscribe to events + OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.requestAcknowledged, () => { + // Transaction is being executed. + }); + + OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowComplete, (ostWorkflowContext , ostContextEntity) => { + // Show success message to user. + // Transaction has been executed successfully. + }); + + OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowInterrupt, (ostWorkflowContext , ostError) => { + // Show error to user. + // An error occoured during the workflow. + }); +---- + +* ++++++with QR Code payload ++++++ + Developer can pass QR code payload to execute transaction. +QR code scanner view won't appear if developer pass payload. + +[source,js] +---- + let uiCallback = new UserPassphrasePrefixDelegate(); + let payload = + /** + * Execute transaction with QR code payload + * @param {String} userId - Ost User id + * @param {String} qrPayload - QR-Code payload + * @param {OstWalletUIWorkflowCallback} uiCallback - callback implementation instances for application communication + * @return {*|number} + */ + let workflowId = OstWalletSdkUI.executeTransactionWithQRPayload(userId, payload, uiCallback); + + // Subscribe to events + OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.requestAcknowledged, () => { + // Device is being authorized. + }); + + OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowComplete, (ostWorkflowContext , ostContextEntity) => { + // Show success message to user. + // Device has been authorized. + }); + + OstWalletSdkUI.subscribe(workflowId, OstWalletSdkUI.EVENTS.flowInterrupt, (ostWorkflowContext , ostError) => { + // Show error to user. + // An error occoured during the workflow. + }); +---- + +* *By Calling function* + Helper method creates session if active sessoin for transction amount is not available. +To execute transaction via helper method, xref:./OstTransactionHelper.adoc[ref here] + +== Ost Wallet UI Events and Listeners + +=== Subscribe + +Subscribe to specified event of UI Workflow + +Supported `EventName` are: + +* requestAcknowledged +* flowComplete +* flowInterrupt + +You can retrive event names from Sdk: + +[source,javascript] +---- +OstWalletSdkUI.EVENTS.requestAcknowledged +OstWalletSdkUI.EVENTS.flowComplete +OstWalletSdkUI.EVENTS.flowInterrupt +---- + +[source,javascript] +---- +/** +* Subscribes to specified event of UI Workflow. +* @param {String} workflowId - Id of the workflow as returned by methods of OstWalletSdkUI +* @param {String} eventName - Name of the event to subscribe to. +* @param {Function} listener - The listener function. +* @param {*} context - The context to invoke the listener with. +* @returns {Boolean} - false if failed to subscribe. +* @public +*/ +OstWalletSdkUI.subscribe( + workflowId, + eventName, + listener, + context +) +---- + +[source,javascript] +---- +/** +* Subscribes once to specified event of UI Workflow. +* @param {String} workflowId - Id of the workflow as returned by methods of OstWalletSdkUI +* @param {String} eventName - Name of the event to subscribe to. +* @param {Function} listener - The listener function. +* @param {*} context - The context to invoke the listener with. +* @returns {Boolean} - false if failed to subscribe. +* @public +*/ +OstWalletSdkUI.subscribeOnce( + workflowId, + eventName, + listener, + context +) +---- + +=== Unsubscribe + +Unsubscribes the listener from the specified event of UI Workflow. + +[source,javascript] +---- +/** +* Unsubscribes the listener from the specified event of UI Workflow. +* @param {String} workflowId - Id of the workflow as returned by methods of OstWalletSdkUI +* @param {String} eventName - Name of the event to subscribe to. +* @param {Function} listener - The listener function. +* @param {*} context - The context to invoke the listener with. +* @returns {Boolean} - false if failed to subscribe. +* @public +*/ +OstWalletSdkUI.unsubscribe( + workflowId, + eventName, + listener, + context +) +---- + +=== Event Listeners + +==== Request Acknowledged Listener + +Acknowledge application about the request which is going to made by SDK. + +[source,js] +---- +/** + * Request acknowledged + * @param {Object} ostWorkflowContext - info about workflow type + * @param ostContextEntity - info about entity + * @override + */ + requestAcknowledged(ostWorkflowContext, ostContextEntity ) => { + //ostWorkflowContext.WORKFLOW_ID gives the id of the workflow. + //ostWorkflowContext.WORKFLOW_TYPE gives the type of the workflow. + } +---- + +==== Flow Complete Listener + +[source,js] +---- +/** + * Flow complete + * @param ostWorkflowContext - workflow type + * @param ostContextEntity - status of the flow + * @override + */ + flowComplete(ostWorkflowContext, ostContextEntity ) => { + //ostWorkflowContext.WORKFLOW_ID gives the id of the workflow. + //ostWorkflowContext.WORKFLOW_TYPE gives the type of the workflow. + } +---- + +==== Flow Interrupt Listener + +[source,js] +---- +/** + * Flow interrupt + * @param ostWorkflowContext workflow type + * @param ostError reason of interruption + * @override + */ + flowInterrupt(ostWorkflowContext, ostError) => { + //ostWorkflowContext.WORKFLOW_ID gives the id of the workflow. + //ostWorkflowContext.WORKFLOW_TYPE gives the type of the workflow. + } +---- diff --git a/docs/modules/ROOT/pages/iOSSetup.adoc b/docs/modules/ROOT/pages/iOSSetup.adoc new file mode 100644 index 0000000..e131a7b --- /dev/null +++ b/docs/modules/ROOT/pages/iOSSetup.adoc @@ -0,0 +1,152 @@ += iOS setup required for OST React Native SDK +:doctype: book + +== 1. Installing https://github.com/Carthage/Carthage[Carthage] + +Get https://github.com/Carthage/Carthage[Carthage] by running following command on terminal + +[source,bash] +---- + brew install carthage +---- + +You can also choose https://github.com/Carthage/Carthage/#installing-carthage[other methods] to install https://github.com/Carthage/Carthage[Carthage] + +== 2. Downloading OST React Native SDK using Carthage + +Carthage looks at a file called `Cartfile` to determine which libraries to install. +Create a file in the `./ios` directory of your react-native project called `Cartfile` and enter the following to tell Carthage which dependencies we want: + +Add following entry in your `Cartfile` + +[source,bash] +---- + github "ostdotcom/ost-wallet-sdk-ios" == 2.4.1 +---- + +Now to actually install everything run the following in your terminal: + +[source,bash] +---- + carthage update --platform iOS +---- + +A `Cartfile.resolved` file and a `Carthage` directory will appear in the same directory where your `.xcodeproj` or `.xcworkspace` is. + +== 3. Copying the `OstWalletSdk.framework` file in your Xcode project + +Open your project in Xcode, click on the project file in the left section of the screen and scroll down to the `Linked Frameworks and Libraries` section in Xcode. + +`Carthage` folder will have the `.framework` files that we will add in Xcode project. + +Now open the `./ios/Carthage/Build/iOS` folder in Finder: + +Run this command + +[source,bash] +---- +open ios/Carthage/Build/iOS +---- + +Open application target, under General tab, drag the built `OstWalletSdk.framework` binary from `./ios/Carthage/Build/iOS` folder into Linked Frameworks and Libraries section. + +image::https://dxwfxs8b4lg24.cloudfront.net/docs/native/images/copy-framework-file.png[copy-framework-file] + +== 4. Adding the `OstWalletSdk` dependencies in your Xcode project + +We need to add the `.framework` files of dependencies present inside `./ios/Carthage/Build/iOS`. + +Open `application targets` in Xcode. +Under `Build Phases` click `+` icon and choose `New Run Script Phase`. +Add the following command. + +[source,bash] +---- +/usr/local/bin/carthage copy-frameworks +---- + +Click the `+` under `Input Files` and add the following entry framework: + +---- +$(SRCROOT)/Carthage/Build/iOS/Alamofire.framework +$(SRCROOT)/Carthage/Build/iOS/BigInt.framework +$(SRCROOT)/Carthage/Build/iOS/CryptoEthereumSwift.framework +$(SRCROOT)/Carthage/Build/iOS/CryptoSwift.framework +$(SRCROOT)/Carthage/Build/iOS/EthereumKit.framework +$(SRCROOT)/Carthage/Build/iOS/FMDB.framework +$(SRCROOT)/Carthage/Build/iOS/SipHash.framework +$(SRCROOT)/Carthage/Build/iOS/TrustKit.framework +$(SRCROOT)/Carthage/Build/iOS/OstWalletSdk.framework +---- + +image::https://dxwfxs8b4lg24.cloudfront.net/docs/native/images/add-dependency-framework-files.png[copy-framework-file] + +== 5. Add additional SDK files + +Follow these steps to add additional files: + +* Click on your project, select `File > Add Files to ""` +* Browse to `./node_modules/@ostdotcom/ost-wallet-sdk-react-native/ios` +* Add the folder `ostwalletrnsdk` with following settings: + ** Destination: (uncheck) Copy items if needed + ** Added folders: (select) Create groups + +image::https://dxwfxs8b4lg24.cloudfront.net/docs/native/images/additional-files.png[Add-image] + +== 6. Change Build Settings + +Open application target, under `Build Settings` tab, enable `Always Embed Swift Standard Libraries` under `Build Options` + +image::https://dxwfxs8b4lg24.cloudfront.net/docs/native/images/build-options.png[Add image] + +== 7. Create SDK configuration file + +Create `OstWalletSdk.plist` file. +This file has configuration attributes used by OstWalletSdk. +You should copy paste the configuration values from below snippet. + +---- + + + + + BlockGenerationTime + 3 + PricePointTokenSymbol + OST + PricePointCurrencySymbol + USD + RequestTimeoutDuration + 30 + PinMaxRetryCount + 3 + SessionBufferTime + 3600 + UseSeedPassword + + EnableIOSDeviceRestore + + + +---- + +. BlockGenerationTime: The time in seconds it takes to mine a block on auxiliary chain. +. PricePointTokenSymbol: This is the symbol of base currency. +So its value will be OST. +. PricePointCurrencySymbol: It is the symbol of quote currency used in price conversion. +. RequestTimeoutDuration: Request timeout in seconds for https calls made by ostWalletSdk. +. PinMaxRetryCount: Maximum retry count to get the wallet Pin from user. +. SessionBufferTime: Buffer expiration time for session keys in seconds. +Default value is 3600 seconds. +. UseSeedPassword: The seed password is salt to PBKDF2 used to generate seed from the mnemonic. +When UseSeedPassword set to `true`, different deterministic salts are used for different keys. +. EnableIOSDeviceRestore: When EnableIOSDeviceRestore is set to `true`, After app re-installation, SDK checks for available device key in Keychain for given user id. + +*These configurations are MANDATORY for successful operation. +Failing to set them will significantly impact usage.* + += Next Steps + +. link:../README.md#sdk-usage[SDK Usage] +. link:../README.md#sdk-methods[SDK Methods] +. link:../README.md#sdk-workflow-callbacks[SDK Callbacks] diff --git a/docs/modules/ROOT/pages/index.adoc b/docs/modules/ROOT/pages/index.adoc new file mode 100644 index 0000000..a3365f6 --- /dev/null +++ b/docs/modules/ROOT/pages/index.adoc @@ -0,0 +1,301 @@ += Ost Client SDK React Native + +== Installation + +* Install React Native and create a react-native project. Follow the https://facebook.github.io/react-native/docs/0.59/getting-started[official React Native getting started guide] to install React Native and create a react-native project + +* Install the Ost React Native Client SDK in your project. Run the following command in your react-native project root + +[source,bash] +---- + npm install @ostdotcom/ost-wallet-SDK-react-native +---- + +* The SDK needs the following peer dependencies: + ** https://www.npmjs.com/package/eventemitter3[eventemitter3] + ** https://www.npmjs.com/package/lodash.merge[lodash.merge] + ** https://www.npmjs.com/package/bignumber.js[bignumber.js] + +[source,bash] +---- + npm install --save lodash.merge + npm install --save eventemitter3 + npm install --save bignumber.js +---- + +* Link the Ost Client SDK with your project + +[source,bash] +---- + react-native link @ostdotcom/ost-wallet-SDK-react-native +---- + +=== Setup Steps For Android And iOS + +xref:AndroidSetup.adoc[Android Set-up] + +xref:iOSSetup.adoc[iOS Set-up] + + +=== Migrating To Another Version + +If you decide to change the SDK version, please make sure to update the downsteam native SDKs. + +For Android, please run: + +[source, shell] +---- +react-native link +react-native run-android +---- + +For iOS, please update the `ios/Cartfile` with desired version and run: + +[source,shell] +---- +carthage update --cache-builds --platform ios +---- + +After updating the SDK, please delete `ostwalletrnSDK` using the *Remove References* option and add it back by following link:../iOSSetup.adoc#5-add-additional-SDK-files[this step]. + +== Usage + +* Initialize the SDK +* Subscribe to events +* Implement `OstWalletWorkFlowCallback` for a workflow +* Execute workflow + +=== Initialize the SDK + +You must initialize the SDK before using it. + +[NOTE] +Initialize the SDK in using BASE_URL (Ost Platform endpoint) inside App.js `constructor()` method. + +[source,javascript] +---- +/** + * Initialize wallet SDK + * @param {String} endpoint - Ost Platform endpoint + * @param {function} Callback function with error and success status. + * @public + */ + OstWalletSDK.initialize( endpoint, + (error, success) => {}) +---- + +[source,javascript] +---- +include::initialize.js +---- + + +=== Initializing SDK With Config + +Starting version `2.3.1` application can also pass SDK config in the initialize method + +[NOTE] +If config is passed in `initialize` method, the configs specified in `OstWalletSDK.plist` and `ost-mobileSDK.json` are ignored. +It is no longer mandatory to define `ost-mobileSDK.json` and `OstWalletSDK.plist` files. + +[source,javascript] +---- + let SDKConfig = { + "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, + "NO_OF_SESSIONS_ON_ACTIVATE_USER": 1, + "ENABLE_IOS_DEVICE_RESTORE": false + }; + + /** + * Initialize wallet SDK + * @param {String} endpoint - Ost Platform endpoint + * @param {Object} config (optional) - SDK Config. Supported from version 2.3.1 + * @param {function} callback - A typical node-style, error-first callback. + * @callback params {Object}error , {Boolean} success + * @public + */ + OstWalletSDK.initialize( endpoint, SDKConfig, (error, success) => { + + }); +---- + +=== Subscribe to `OstWalletSDKEvents` in your top most level component + +In the most top level component [mostly `App.js`] import like this: + +[source,javascript] +---- +import { OstWalletSDKEvents, OstWalletSDK, OstWalletSDKUI, OstJsonAPI } from '@ostdotcom/ost-wallet-SDK-react-native'; +---- + +In `componentDidMount()` subscribe to OstWalletSDKEvents and in `componentWillUnmount()` unsubscribe to OstWalletSDKEvents. Also initialize the SDK in using BASE_URL (Ost Platform endpoint) `constructor()` method: + +[source,javascript] +---- +class App extends Component { + + constructor() { + super(); + OstWalletSDK.initialize(BASE_URL, (error, success) => { + if(error) { + console.warn(error); + } + else { + console.warn(success); + } + + }); + } + + componentDidMount() { + OstWalletSDKEvents.subscribeEvent(); + } + + componentWillUnmount() { + OstWalletSDKEvents.unsubscribeEvent(); + } + +} +---- + +== Getter Methods + +The SDK provides getter methods that applications can use for various purposes. These methods provide the application with data as available in the device's database. + +Please refer to xref:OstWalletSDKGetMethods.adoc[Ost Wallet SDK Getter Methods] for documentation. + +== Ost JSON APIs + +While the getter methods provide application with data stored in device's database, the JSON API methods make API calls to Ost Platform servers. + +Please refer to xref:OstJsonAPI.adoc[Ost JSON API] for documentation. + +== Quick Start Guide + +Starting version 2.3.12-beta.1, developers can enable all the Ost wallet features implementing the *Ost Macro Workflows.* + +=== 1. Setup Device Core Workflow + +The setup device workflow establishes trust between the device and Ost Platform. As application is responsible for user authentication, application servers must facilitate this workflow using the server side SDK. + +==== Workflow Details + +* When this workflow is initiated by the application, the SDK creates the following keys: + ** API key - the key used to sign API requests sent to Ost Platform from the SDK + ** Device key - the user's wallet device key. All device manager operations shall be performed using this key. +* The SDK asks the application to register the device entity with Ost Platform +* The application must send the device entity to the application server +* The application server must then use the server side SDK to register the device with Ost Plaform by using device service's create device API. +* Once the device is registered by the Ost Platform, the application server must send the response to the mobile application. +* The mobile application must then use the `deviceRegistered` callbacks to provide the response to the SDK. +* The SDK validates the registration by making API calls to the Ost Plaform. + +image::setup_device_workflow.svg[setup device workflow] + +[NOTE] +==== +* Setup device workflow must be initiated *on every app launch*. +* Setup device workflow must be initiated only *after the user has been autheniticated* by the application, including cookie based authentication for already logged-in users. +* Each of user's device creates its own API key and device key. +* User's Device and API keys are not shared across devices. +* User's API key & device key are stored in persistent storage on the device and created only if needed. +* The SDK shall request for device registration only when needed. +`registerDevice` shall not be invoked if device is already authorized and SDK is able to make API calls to Ost Platform. +==== + +==== Implementation + +Please refer to xref:OstCoreWorkflows.adoc#setupdevice[`setupDevice` core workflow documentation] for implementation details. + +=== 2. Activate User UI Workflow + +Activate User workflow deploys user's wallet on the blockchain and whitelists the user's wallet and enables it to take part in application's brand token economy. + +==== Blockchain Transactions Performed During Activate User Workflow + +* Deploys user's contracts + ** Device-manager and token-holder contracts + ** Set user's recovery key address, device key address in device-manager contract + ** Authorizes session key(s) in token-holder contract +* Whitelists user's contract in UBT (Utility Brand Token Contract). + +==== Recovery Key Generation Using 6 Digit Pin + +* User's recovery key is generated using https://en.bitcoinwiki.org/wiki/Scrypt[SCrypt], a password-based key derivation function. +* The '`password`' provided to this function is a string created by concatenating: +* A prefix provided by application server. + +Application server must generate and store prefix for each user, treat it as sensitive and immutable information. + +* User's PIN +* User's Ost-id +* The salt required for SCrypt is provided by Ost Platform + +==== Implementation + +Please refer to xref:OstWalletUI.adoc#activate-user[Activate User UI Workflow Documentation] for implementation details. + +=== 3. Wallet Settings UI Component + +OstWallet Settings is a pre-built UI component available exclusively available in `ost-wallet-SDK-react-native` SDK. It is a wallet settings page that can be used by end-users to perfrom 12 different wallet operations and view their wallet details. + +[WARNING] +This feature requires application to use https://reactnavigation.org/docs/en/getting-started.html[React Navigation] package. + +==== Implementation + +Please refer to xref:OstWalletSettings.adoc[OstWallet Settings Documentation] for implementation details. + +=== 4. Redemption Flow UI Component + +OstRedemption component is a pre-built UI component available exclusively in `ost-wallet-SDK-react-native` SDK. It consist two pages - one displaying redeemable product list and another displaying product details and redemption options. It can be used by end-users to integrate redemption flow into their app. + +[WARNING] +This feature requires application to use https://reactnavigation.org/docs/en/getting-started.html[React Navigation] package. + +==== Implementation + +Please reder to xref:OstRedemptionFlow.adoc[OstRedemption flow Documentation] for implementation details. + +=== 5. OstTransaction Helper - Transaction and Add Session Integrated Workflow + +`OstTransactionHelper` is a transaction helper provided by the SDK that creates session keys before performing a transaction if needed. App developers can configure the session creation parameters (session buckets) as per application's need. + +==== Implementation + +Please refer to xref:OstTransactionHelper.adoc[Ost Transaction Helper Documentation] for implementation details. + +== Intermediate Usage - Ost Wallet SDK UI + +For quick and easy integration with SDK, developers can use built-in user-interface components which are configurable and support content and theme customization. + +Please refer to xref:OstWalletUI.adoc[Ost Wallet SDK UI] for documentation. + +== Advance Usage - Ost Wallet Core Workflow APIs + +Ost core workflows API do not use any UI components, thereby giving complete ux control to the developers. The xref:OstWalletUI.adoc[`OstWalletSDKUI`] also uses Ost core workflows. + +Please refer to xref:./documentation/OstCoreWorkflows.adoc[Ost Core Workflow APIs] for documentation. + +== Known Issues + +=== SDK Initialization Fails on Android 9 (API level 28) + +Starting with Android 9 (API level 28), https://developer.android.com/training/articles/security-config#CleartextTrafficPermitted[cleartext support] is disabled by default. + +On the other hand, Ost Wallet Android SDK leverages on *Public Key Pinning* to ensure the authenticity of a Ost Platform server's public key used in TLS sessions using https://github.com/datatheorem/TrustKit-Android[TrustKit]. + +As TrustKit can only be inititialized with application's https://developer.android.com/training/articles/security-config[network security configuration], SDK initialization fails. + +To work-around this issues, application needs to have TrustKit as a dependency and initialize it. + +=== Setup Device Workflow Fails on iOS-13 Simulator + +Ost Wallet SDK uses iOS's https://developer.apple.com/documentation/security/certificate_key_and_trust_services/keys/storing_keys_in_the_keychain[Keychain] to store user's cryptographic keys. +Unfortunately, Keychain doesn't work as expected on iOS-13 Simulators. +We request you to kindly test your application on actual iOS-13 device while we continue to look for a workaround. \ No newline at end of file