@appboxo/expo-boxo-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc.js ADDED
@@ -0,0 +1,5 @@
1
+ module.exports = {
2
+ root: true,
3
+ extends: ['universe/native', 'universe/web'],
4
+ ignorePatterns: ['build'],
5
+ };
package/README.md ADDED
@@ -0,0 +1,242 @@
1
+ # expo-boxo-sdk
2
+
3
+ Expo wrapper over Appboxo SDK for IOS and Android.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @appboxo/expo-boxo-sdk
9
+ ```
10
+
11
+ ## API
12
+
13
+ * [`setConfig(...)`](#setconfig)
14
+ * [`openMiniapp(...)`](#openminiapp)
15
+ * [`setAuthCode(...)`](#setauthcode)
16
+ * [`closeMiniapp(...)`](#closeminiapp)
17
+ * [`sendCustomEvent(...)`](#sendcustomevent)
18
+ * [`sendPaymentEvent(...)`](#sendpaymentevent)
19
+ * [`getMiniapps()`](#getminiapps)
20
+ * [`hideMiniapps()`](#hideminiapps)
21
+ * [`logout()`](#logout)
22
+ * [`addAuthListener( ...)`](#AuthListener)
23
+ * [`addCustomEventListener()`](#CustomEventListener)
24
+ * [`addPaymentEventListener()`](#PaymentEventListener)
25
+ * [`addMiniappLifecycleListener()`](#MiniappLifecycleListener)
26
+ * [`addMiniappListListener()`](#MiniappListListener)
27
+
28
+ ### setConfig(...)
29
+
30
+ ```typescript
31
+ setConfig(options: ConfigOptions)
32
+ ```
33
+
34
+ Set global configs
35
+
36
+ | Prop | Type | Description |
37
+ |---------------------------| ------------------------------------------ | ---------------------------------------------------------------------------------------- |
38
+ | **`clientId`** | <code>string</code> | your client id from dashboard |
39
+ | **`userId`** | <code>string</code> | hostapp userId, will be used for the Consent Management |
40
+ | **`sandboxMode`** | <code>boolean</code> | switch to sandbox mode |
41
+ | **`multitaskMode`** | <code>boolean</code> | Each miniapp appears as a task in the Recents screen. !It works only on android devices. |
42
+ | **`theme`** | <code>'light' \| 'dark' \| 'system'</code> | theme for splash screen and other native components used inside miniapp. |
43
+ | **`isDebug`** | <code>boolean</code> | enables webview debugging |
44
+ | **`showPermissionsPage`** | <code>boolean</code> | use it to hide "Settings" from Miniapp menu |
45
+ | **`showClearCache`** | <code>boolean</code> | use it to hide "Clear cache" from Miniapp menu |
46
+
47
+
48
+ --------------------
49
+
50
+
51
+ ### openMiniapp(...)
52
+
53
+ ```typescript
54
+ openMiniapp(options: MiniappOptions)
55
+ ```
56
+
57
+ Open miniapp with options
58
+
59
+ | Prop | Type | Description |
60
+ | -------------------- |--------------------------------------------| ------------------------------------------------------------------------------------------------- |
61
+ | **`appId`** | <code>string</code> | miniapp id |
62
+ | **`data`** | <code>Record<string, any></code> | (optional) data as Map that is sent to miniapp |
63
+ | **`theme`** | <code>'light' \| 'dark' \| 'system'</code> | (optional) miniapp theme "dark" \| "light" (by default is system theme) |
64
+ | **`extraUrlParams`** | <code>Record<string, string></code> | (optional) extra query params to append to miniapp URL (like: http://miniapp-url.com/?param=test) |
65
+ | **`urlSuffix`** | <code>string</code> | (optional) suffix to append to miniapp URL (like: http://miniapp-url.com/?param=test) |
66
+ | **`colors`** | <code>Record<string, string></code> | (optional) provide colors to miniapp if miniapp supports |
67
+ | **`enableSplash`** | <code>boolean</code> | (optional) use to skip miniapp splash screen |
68
+
69
+ Color options
70
+
71
+ | Prop | Type |
72
+ | -------------------- | ------------------- |
73
+ | **`primaryColor`** | <code>string</code> |
74
+ | **`secondaryColor`** | <code>string</code> |
75
+ | **`tertiaryColor`** | <code>string</code> |
76
+
77
+ --------------------
78
+
79
+
80
+ ### setAuthCode(...)
81
+
82
+ ```typescript
83
+ setAuthCode(appId: string, authCode: string)
84
+ ```
85
+
86
+ get AuthCode from hostapp backend and send it to miniapp
87
+
88
+ --------------------
89
+
90
+
91
+ ### closeMiniapp(...)
92
+
93
+ ```typescript
94
+ closeMiniapp(appId: string)
95
+ ```
96
+
97
+ close miniapp by appId
98
+
99
+ --------------------
100
+
101
+
102
+ ### sendCustomEvent(...)
103
+
104
+ ```typescript
105
+ sendCustomEvent(customEventData: CustomEventData)
106
+ ```
107
+
108
+ send custom event to miniapp
109
+
110
+ | Prop | Type |
111
+ | --------------- | ------------------- |
112
+ | **`appId`** | <code>string</code> |
113
+ | **`requestId`** | <code>number</code> |
114
+ | **`type`** | <code>string</code> |
115
+ | **`errorType`** | <code>string</code> |
116
+ | **`payload`** | <code>object</code> |
117
+
118
+
119
+ --------------------
120
+
121
+
122
+ ### sendPaymentEvent(...)
123
+
124
+ ```typescript
125
+ sendPaymentEvent(paymentData: PaymentData)
126
+ ```
127
+
128
+ send payment data to miniapp
129
+
130
+ | Prop | Type |
131
+ | ---------------------- | ------------------- |
132
+ | **`appId`** | <code>string</code> |
133
+ | **`transactionToken`** | <code>string</code> |
134
+ | **`miniappOrderId`** | <code>string</code> |
135
+ | **`amount`** | <code>number</code> |
136
+ | **`currency`** | <code>string</code> |
137
+ | **`status`** | <code>string</code> |
138
+ | **`hostappOrderId`** | <code>string</code> |
139
+ | **`extraParams`** | <code>object</code> |
140
+
141
+
142
+ --------------------
143
+
144
+
145
+ ### getMiniapps()
146
+
147
+ ```typescript
148
+ getMiniapps()
149
+ ```
150
+ Get list of miniapps. To get results subscribe to
151
+ * [`addMiniappListListener()`](#MiniappListListener)
152
+ --------------------
153
+
154
+
155
+ ### hideMiniapps()
156
+
157
+ ```typescript
158
+ hideMiniapps()
159
+ ```
160
+
161
+ Miniapp opens on a native screen. To show payment processing page need to hide miniapp screen.
162
+ To use this function need to enable 'enableMultitaskMode: true' in Appboxo.setConfigs()
163
+
164
+ --------------------
165
+
166
+ ### logout()
167
+
168
+ ```typescript
169
+ logout()
170
+ ```
171
+ When host app user logs out, it is highly important to clear all miniapp storage data.
172
+
173
+ --------------------
174
+
175
+ #### AuthListener
176
+
177
+ ```typescript
178
+ Boxo.addAuthListener((authEvent) => {
179
+ Boxo.setAuthCode(authEvent.appId, authCode)
180
+ });
181
+ ```
182
+
183
+ #### CustomEventListener
184
+
185
+ ```typescript
186
+ Boxo.addCustomEventListener((customEvent) => {
187
+ ..handle custom event
188
+ });
189
+ ```
190
+
191
+ #### PaymentEventListener
192
+
193
+ ```typescript
194
+ Boxo.addPaymentEventListener((paymentData) => {
195
+ Boxo.hideMiniapps();
196
+ .. show payment page
197
+ paymentData.status = "success";
198
+ ..confirm payment
199
+ Boxo.sendPaymentEvent(paymentData);
200
+ Boxo.openMiniapp({ appId: paymentData.appId })
201
+ });
202
+ ```
203
+
204
+ #### MiniappLifecycleListener
205
+
206
+ ```typescript
207
+ Boxo.addMiniappLifecycleListener((lifecycleData) => {
208
+ console.log(lifecycleData);
209
+ });
210
+ ```
211
+
212
+ | Prop | Type | Description |
213
+ | --------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
214
+ | **`appId`** | <code>string</code> | |
215
+ | **`lifecycle`** | <code>string</code> | onLaunch - Called when the miniapp will launch with Appboxo.open(...) onResume - Called when the miniapp will start interacting with the user onPause - Called when the miniapp loses foreground state onClose - Called when clicked close button in miniapp or when destroyed miniapp page onError - Called when miniapp fails to launch due to internet connection issues onUserInteraction - Called whenever touch event is dispatched to the miniapp page. onAuth - Called when the miniapp starts login and user allows it |
216
+ | **`error`** | <code>string</code> | |
217
+
218
+
219
+ #### MiniappListListener
220
+
221
+ ```typescript
222
+ Boxo.addMiniappListListener((result) => {
223
+ console.log(result.miniapps);
224
+ });
225
+ ```
226
+
227
+ Get miniapp list
228
+
229
+ | Prop | Type |
230
+ | -------------- | -------------------------- |
231
+ | **`miniapps`** | <code>[MiniappData]</code> |
232
+ | **`error`** | <code>string</code> |
233
+
234
+ MiniappData
235
+
236
+ | Prop | Type |
237
+ | ----------------- | ------------------- |
238
+ | **`appId`** | <code>string</code> |
239
+ | **`name`** | <code>string</code> |
240
+ | **`category`** | <code>string</code> |
241
+ | **`description`** | <code>string</code> |
242
+ | **`logo`** | <code>string</code> |
@@ -0,0 +1,63 @@
1
+ apply plugin: 'com.android.library'
2
+
3
+ group = 'io.boxo.expo'
4
+ version = '0.1.0'
5
+
6
+ def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
7
+ apply from: expoModulesCorePlugin
8
+ applyKotlinExpoModulesCorePlugin()
9
+ useCoreDependencies()
10
+ useExpoPublishing()
11
+
12
+ // If you want to use the managed Android SDK versions from expo-modules-core, set this to true.
13
+ // The Android SDK versions will be bumped from time to time in SDK releases and may introduce breaking changes in your module code.
14
+ // Most of the time, you may like to manage the Android SDK versions yourself.
15
+ def useManagedAndroidSdkVersions = false
16
+ if (useManagedAndroidSdkVersions) {
17
+ useDefaultAndroidSdkVersions()
18
+ } else {
19
+ buildscript {
20
+ // Simple helper that allows the root project to override versions declared by this library.
21
+ ext.safeExtGet = { prop, fallback ->
22
+ rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
23
+ }
24
+ }
25
+ project.android {
26
+ compileSdkVersion safeExtGet("compileSdkVersion", 34)
27
+ defaultConfig {
28
+ minSdkVersion safeExtGet("minSdkVersion", 21)
29
+ targetSdkVersion safeExtGet("targetSdkVersion", 34)
30
+ }
31
+ }
32
+ }
33
+
34
+ rootProject.allprojects {
35
+ repositories {
36
+ google()
37
+ mavenCentral()
38
+ maven { url "https://jitpack.io" }
39
+ maven {
40
+ url "https://maven.pkg.github.com/Appboxo/android-sdk-packages"
41
+ credentials {
42
+ username = "appboxoandroidsdk"
43
+ password = "\u0037\u0039\u0064\u0031\u0065\u0064\u0061\u0036\u0030\u0034\u0063\u0061\u0031\u0066\u0030\u0032\u0066\u0031\u0037\u0066\u0032\u0061\u0039\u0033\u0064\u0035\u0039\u0039\u0061\u0035\u0035\u0062\u0066\u0065\u0031\u0064\u0066\u0064\u0038\u0038"
44
+ }
45
+ }
46
+ }
47
+ }
48
+
49
+ android {
50
+ namespace "io.boxo.expo"
51
+ defaultConfig {
52
+ versionCode 1
53
+ versionName "0.1.0"
54
+ }
55
+ lintOptions {
56
+ abortOnError false
57
+ }
58
+ }
59
+ dependencies {
60
+ implementation('com.appboxo:sdk:1.5.18') {
61
+ exclude group: 'com.google.android.gms', module: 'play-services-location'
62
+ }
63
+ }
@@ -0,0 +1,2 @@
1
+ <manifest>
2
+ </manifest>
@@ -0,0 +1,33 @@
1
+ package io.boxo.expo
2
+
3
+ import expo.modules.kotlin.records.Field
4
+ import expo.modules.kotlin.records.Record
5
+
6
+ class ConfigOptions : Record {
7
+ @Field
8
+ val clientId: String = ""
9
+
10
+ @Field
11
+ val userId: String = ""
12
+
13
+ @Field
14
+ val language: String = "en"
15
+
16
+ @Field
17
+ val sandboxMode: Boolean = false
18
+
19
+ @Field
20
+ val multitaskMode: Boolean = false
21
+
22
+ @Field
23
+ val theme: String = "system"
24
+
25
+ @Field
26
+ val isDebug: Boolean = false
27
+
28
+ @Field
29
+ val showPermissionsPage: Boolean = true
30
+
31
+ @Field
32
+ val showClearCache: Boolean = true
33
+ }
@@ -0,0 +1,21 @@
1
+ package io.boxo.expo
2
+
3
+ import expo.modules.kotlin.records.Field
4
+ import expo.modules.kotlin.records.Record
5
+
6
+ class CustomEventData : Record {
7
+ @Field
8
+ val appId: String = ""
9
+
10
+ @Field
11
+ val requestId: Int? = null
12
+
13
+ @Field
14
+ val type: String? = null
15
+
16
+ @Field
17
+ val errorType: String? = null
18
+
19
+ @Field
20
+ val payload: Map<String, Any>? = null
21
+ }
@@ -0,0 +1,231 @@
1
+ package io.boxo.expo
2
+
3
+ import android.os.Handler
4
+ import android.os.Looper
5
+ import com.appboxo.data.models.MiniappData
6
+ import com.appboxo.js.params.CustomEvent
7
+ import com.appboxo.js.params.PaymentData
8
+ import expo.modules.kotlin.modules.Module
9
+ import expo.modules.kotlin.modules.ModuleDefinition
10
+ import expo.modules.kotlin.Promise
11
+ import com.appboxo.sdk.*
12
+
13
+ class ExpoBoxoSdkModule : Module() {
14
+ private var handler: Handler? = null
15
+
16
+ override fun definition() = ModuleDefinition {
17
+ Name("ExpoBoxoSdk")
18
+
19
+ handler = Handler(Looper.getMainLooper())
20
+
21
+ Events("customEvent", "paymentEvent", "miniappLifecycle", "onAuth", "miniappList")
22
+
23
+ Function("setConfig") { options: ConfigOptions ->
24
+ val globalTheme: Config.Theme = when (options.theme) {
25
+ "light" -> Config.Theme.LIGHT
26
+ "dark" -> Config.Theme.DARK
27
+ else -> Config.Theme.SYSTEM
28
+ }
29
+ Appboxo.init(appContext.activityProvider!!.currentActivity.application)
30
+ .setConfig(
31
+ Config.Builder()
32
+ .setClientId(options.clientId)
33
+ .setUserId(options.userId)
34
+ .sandboxMode(options.sandboxMode)
35
+ .multitaskMode(options.multitaskMode)
36
+ .setTheme(globalTheme)
37
+ .setLanguage(options.language)
38
+ .permissionsPage(options.showPermissionsPage)
39
+ .showClearCache(options.showClearCache)
40
+ .debug(options.isDebug)
41
+ .build()
42
+ )
43
+ }
44
+
45
+ Function("openMiniapp") { options: MiniappOptions ->
46
+ val miniapp: Miniapp = Appboxo.getMiniapp(options.appId)
47
+ .setCustomEventListener { _, miniapp, customEvent ->
48
+ sendEvent(
49
+ "customEvent", mapOf(
50
+ "appId" to miniapp.appId,
51
+ "requestId" to customEvent.requestId,
52
+ "type" to customEvent.type,
53
+ "errorType" to customEvent.errorType,
54
+ "payload" to customEvent.payload,
55
+ )
56
+ )
57
+ }
58
+ .setPaymentEventListener { _, miniapp, paymentData ->
59
+ sendEvent(
60
+ "paymentEvent", mapOf(
61
+ "appId" to miniapp.appId,
62
+ "transactionToken" to paymentData.transactionToken,
63
+ "miniappOrderId" to paymentData.miniappOrderId,
64
+ "amount" to paymentData.amount,
65
+ "currency" to paymentData.currency,
66
+ "extraParams" to paymentData.extraParams,
67
+ "hostappOrderId" to paymentData.hostappOrderId,
68
+ "status" to paymentData.status,
69
+ )
70
+ )
71
+ }
72
+ .setAuthListener { _, miniapp ->
73
+ sendEvent("onAuth", mapOf("appId" to miniapp.appId))
74
+ }
75
+ .setLifecycleListener(object : Miniapp.LifecycleListener {
76
+ override fun onClose(miniapp: Miniapp) {
77
+ sendEvent(
78
+ "miniappLifecycle", mapOf(
79
+ "appId" to miniapp.appId,
80
+ "lifecycle" to "onClose"
81
+ )
82
+ )
83
+ }
84
+
85
+ override fun onError(miniapp: Miniapp, message: String) {
86
+ sendEvent(
87
+ "miniappLifecycle", mapOf(
88
+ "appId" to miniapp.appId,
89
+ "lifecycle" to "onError",
90
+ "error" to message
91
+ )
92
+ )
93
+ }
94
+
95
+ override fun onLaunch(miniapp: Miniapp) {
96
+ sendEvent(
97
+ "miniappLifecycle", mapOf(
98
+ "appId" to miniapp.appId,
99
+ "lifecycle" to "onLaunch"
100
+ )
101
+ )
102
+ }
103
+
104
+ override fun onPause(miniapp: Miniapp) {
105
+ sendEvent(
106
+ "miniappLifecycle", mapOf(
107
+ "appId" to miniapp.appId,
108
+ "lifecycle" to "onPause"
109
+ )
110
+ )
111
+ }
112
+
113
+ override fun onResume(miniapp: Miniapp) {
114
+ sendEvent(
115
+ "miniappLifecycle", mapOf(
116
+ "appId" to miniapp.appId,
117
+ "lifecycle" to "onResume"
118
+ )
119
+ )
120
+ }
121
+
122
+ override fun onUserInteraction(miniapp: Miniapp) {
123
+ sendEvent(
124
+ "miniappLifecycle", mapOf(
125
+ "appId" to miniapp.appId,
126
+ "lifecycle" to "onUserInteraction"
127
+ )
128
+ )
129
+ }
130
+ })
131
+ if (options.data != null) miniapp.setData(options.data)
132
+ val configBuilder = MiniappConfig.Builder()
133
+ if (options.theme != null) {
134
+ val miniappTheme: Config.Theme? = when (options.theme) {
135
+ "light" -> Config.Theme.LIGHT
136
+ "dark" -> Config.Theme.DARK
137
+ "system" -> Config.Theme.SYSTEM
138
+ else -> null
139
+ }
140
+ if (miniappTheme != null) {
141
+ configBuilder.setTheme(miniappTheme)
142
+ }
143
+ }
144
+ options.extraUrlParams?.also { extraUrlParams ->
145
+ val stringMap: MutableMap<String, String> = HashMap()
146
+ for ((key, value) in extraUrlParams) stringMap[key] = value.toString()
147
+ configBuilder.setExtraUrlParams(stringMap)
148
+ }
149
+ options.urlSuffix?.also { suffix -> configBuilder.setUrlSuffix(suffix) }
150
+ options.colors?.also { colors ->
151
+ configBuilder.setColors(
152
+ colors["primaryColor"] ?: "",
153
+ colors["secondaryColor"] ?: "",
154
+ colors["tertiaryColor"] ?: "",
155
+ )
156
+ }
157
+ configBuilder.enableSplash(options.enableSplash)
158
+ configBuilder.saveState(options.saveState)
159
+ miniapp.setConfig(configBuilder.build())
160
+ miniapp.open(appContext.currentActivity!!)
161
+ }
162
+
163
+ Function("setAuthCode") { appId: String, authCode: String ->
164
+ Appboxo.getMiniapp(appId)
165
+ .setAuthCode(authCode)
166
+ }
167
+
168
+ Function("sendCustomEvent") { customEvent: CustomEventData ->
169
+ handler?.post {
170
+ Appboxo.getMiniapp(customEvent.appId)
171
+ .sendEvent(
172
+ CustomEvent(
173
+ requestId = customEvent.requestId,
174
+ type = customEvent.type ?: "",
175
+ errorType = customEvent.errorType,
176
+ payload = customEvent.payload ?: emptyMap()
177
+ )
178
+ )
179
+ }
180
+ }
181
+
182
+ Function("sendPaymentEvent") { paymentEvent: PaymentEventData ->
183
+ handler?.post {
184
+ Appboxo.getMiniapp(paymentEvent.appId)
185
+ .sendPaymentResult(
186
+ PaymentData(
187
+ transactionToken = paymentEvent.transactionToken ?: "",
188
+ miniappOrderId = paymentEvent.miniappOrderId ?: "",
189
+ amount = paymentEvent.amount ?: 0.0,
190
+ currency = paymentEvent.currency ?: "",
191
+ status = paymentEvent.status ?: "",
192
+ hostappOrderId = paymentEvent.hostappOrderId ?: "",
193
+ extraParams = paymentEvent.extraParams
194
+ )
195
+ )
196
+ }
197
+ }
198
+
199
+ Function("closeMiniapp") { appId: String ->
200
+ Appboxo.getExistingMiniapp(appId)?.close()
201
+ }
202
+
203
+ Function("hideMiniapps") {
204
+ Appboxo.hideMiniapps()
205
+ }
206
+
207
+ Function("logout") {
208
+ Appboxo.logout()
209
+ }
210
+
211
+ Function("getMiniapps") {
212
+ Appboxo.getMiniapps(object : MiniappListCallback {
213
+ override fun onFailure(e: Exception) {
214
+ sendEvent("miniappList", mapOf("error" to e.toString()))
215
+ }
216
+
217
+ override fun onSuccess(miniapps: List<MiniappData>) {
218
+ sendEvent("miniappList", mapOf("miniapps" to miniapps.map {
219
+ mapOf(
220
+ "name" to it.name,
221
+ "description" to it.description,
222
+ "appId" to it.appId,
223
+ "logo" to it.logo,
224
+ "category" to it.category,
225
+ )
226
+ }))
227
+ }
228
+ })
229
+ }
230
+ }
231
+ }
@@ -0,0 +1,30 @@
1
+ package io.boxo.expo
2
+
3
+ import expo.modules.kotlin.records.Field
4
+ import expo.modules.kotlin.records.Record
5
+
6
+ class MiniappOptions : Record {
7
+ @Field
8
+ val appId: String = ""
9
+
10
+ @Field
11
+ val data: Map<String, Any>? = null
12
+
13
+ @Field
14
+ val theme: String? = null
15
+
16
+ @Field
17
+ val extraUrlParams: Map<String, Any>? = null
18
+
19
+ @Field
20
+ val urlSuffix: String? = null
21
+
22
+ @Field
23
+ val colors: Map<String, String>? = null
24
+
25
+ @Field
26
+ val enableSplash: Boolean = true
27
+
28
+ @Field
29
+ val saveState: Boolean = true
30
+ }
@@ -0,0 +1,30 @@
1
+ package io.boxo.expo
2
+
3
+ import expo.modules.kotlin.records.Field
4
+ import expo.modules.kotlin.records.Record
5
+
6
+ class PaymentEventData : Record {
7
+ @Field
8
+ val appId: String = ""
9
+
10
+ @Field
11
+ val transactionToken: String? = null
12
+
13
+ @Field
14
+ val miniappOrderId: String? = null
15
+
16
+ @Field
17
+ val currency: String? = null
18
+
19
+ @Field
20
+ val amount: Double? = null
21
+
22
+ @Field
23
+ val hostappOrderId: String? = null
24
+
25
+ @Field
26
+ val status: String? = null
27
+
28
+ @Field
29
+ val extraParams: Map<String, Any>? = null
30
+ }