Skip to content

Commit 273ee19

Browse files
author
Yevhen Podkovyrin
committed
Release 1.0.13
1 parent b0c48c7 commit 273ee19

20 files changed

Lines changed: 364 additions & 142 deletions

File tree

README.md

Lines changed: 42 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -6,69 +6,25 @@ In the current release, Flexa offers a privacy-focused payments experience for i
66

77
## Modules structure
88

9-
```mermaid
10-
flowchart BT
11-
direction RL
12-
core([Flexa])
13-
direction TB
14-
scan([Scan])
15-
spend([Spend])
16-
scan---core
17-
spend---core
18-
```
19-
209
| Module | Description |
2110
| ------------- | ------------------------------------------------------ |
2211
| Flexa | Core functionality required by all other modules |
23-
| Scan | Camera-based parsing of QR codes for payments and more |
2412
| Spend | Instant retail payments, powered by Flexa |
2513

2614
## Installation
2715

28-
Flexa can be integrated **locally** or using **package repository**
29-
30-
### Local repository
31-
32-
1. Run the next buildScript from the SDK root folder:
33-
34-
```groovy
35-
./gradlew core:assembleDebug && ./gradlew core:publishToMavenLocal && ./gradlew scan:assembleDebug && ./gradlew scan:publishToMavenLocal && ./gradlew spend:assembleDebug && ./gradlew spend:publishToMavenLocal
36-
37-
```
38-
39-
2. Add `mavenLocal()` repository to `settings.gradle`:
40-
41-
```groovy
42-
dependencyResolutionManagement {
43-
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
44-
repositories {
45-
...
46-
mavenLocal() <---
47-
}
48-
}
49-
```
50-
51-
3. Add module dependency in your project [module-level build.gradle](https://developer.android.com/studio/build#module-level) file:
16+
Flexa can be integrated using **package repository** or **locally**
5217

53-
**Identity** module:
18+
### Package repository
5419

55-
```groovy
56-
implementation "com.flexa:core:1.0.12"
57-
```
58-
59-
**Scan** module:
60-
61-
```groovy
62-
implementation "com.flexa:scan:1.0.12"
63-
```
64-
65-
**Spend** module:
20+
#### Maven Central
6621

22+
Add module dependency in your project [module-level build.gradle](https://developer.android.com/studio/build#module-level) file:
6723
```groovy
68-
implementation "com.flexa:spend:1.0.12"
24+
implementation 'co.flexa:core:1.0.13'
25+
implementation 'co.flexa:spend:1.0.13' // includes core library
6926
```
7027

71-
### Remote repository
7228

7329
#### GitHub Package Registry
7430

@@ -101,27 +57,55 @@ implementation "com.flexa:spend:1.0.12"
10157
}
10258
}
10359
```
104-
60+
10561
3. Add module dependency in your project [module-level build.gradle](https://developer.android.com/studio/build#module-level) file:
10662

10763
**Identity** module:
10864

10965
```groovy
110-
implementation "com.flexa:core:1.0.12"
66+
implementation "com.flexa:core:1.0.13"
11167
```
11268

113-
**Scan** module:
69+
**Spend** module:
11470

11571
```groovy
116-
implementation "com.flexa:scan:1.0.12"
72+
implementation "com.flexa:spend:1.0.13"
11773
```
11874

119-
**Spend** module:
75+
### Local repository
12076

121-
```groovy
122-
implementation "com.flexa:spend:1.0.12"
123-
```
77+
1. Run the next buildScript from the SDK root folder:
78+
79+
```groovy
80+
./gradlew core:assembleDebug && ./gradlew core:publishToMavenLocal && ./gradlew spend:assembleDebug && ./gradlew spend:publishToMavenLocal
81+
82+
```
83+
84+
2. Add `mavenLocal()` repository to `settings.gradle`:
85+
86+
```groovy
87+
dependencyResolutionManagement {
88+
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
89+
repositories {
90+
...
91+
mavenLocal() <---
92+
}
93+
}
94+
```
95+
96+
3. Add module dependency in your project [module-level build.gradle](https://developer.android.com/studio/build#module-level) file:
12497

98+
**Identity** module:
99+
100+
```groovy
101+
implementation "com.flexa:core:1.0.13"
102+
```
103+
104+
**Spend** module:
105+
106+
```groovy
107+
implementation "com.flexa:spend:1.0.13"
108+
```
125109

126110
## Usage
127111

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ buildscript {
22
ext {
33
kotlinVersion = '1.9.21'
44

5-
sdk_version = '1.0.12'
5+
sdk_version = '1.0.13'
66
groupId = 'com.flexa'
77
core_version = sdk_version
88
scan_version = sdk_version

core/src/main/java/com/flexa/core/Flexa.kt

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
2323
import kotlinx.coroutines.flow.StateFlow
2424
import kotlinx.coroutines.flow.asStateFlow
2525
import kotlinx.coroutines.launch
26+
import kotlinx.serialization.encodeToString
2627
import java.util.UUID
2728

2829

@@ -76,7 +77,7 @@ object Flexa {
7677
fun init(config: FlexaClientConfiguration) {
7778
context = config.context.applicationContext
7879
themeConfig = config.theme
79-
setAppAccounts(config.assetAccounts)
80+
setAssetAccounts(config.assetAccounts)
8081
setUniqueIdentifier()
8182
saveApiKeys(
8283
publishableKey = config.publishableKey,
@@ -85,7 +86,8 @@ object Flexa {
8586
}
8687

8788
fun updateAssetAccounts(assetAccounts: ArrayList<AssetAccount>) {
88-
setAppAccounts(assetAccounts)
89+
setAssetAccounts(assetAccounts)
90+
storeAssetAccounts(assetAccounts)
8991
}
9092

9193
fun selectedAsset(appAccountId: String, assetId: String) {
@@ -122,9 +124,22 @@ object Flexa {
122124
}
123125
}
124126

125-
private fun setAppAccounts(appAccounts: List<AssetAccount>?) {
127+
private fun setAssetAccounts(appAccounts: List<AssetAccount>?) {
126128
scope.launch {
127-
appAccounts?.let { _appAccounts.emit(it) }
129+
appAccounts?.let {
130+
_appAccounts.emit(it)
131+
storeAssetAccounts(it)
132+
}
133+
}
134+
}
135+
136+
private fun storeAssetAccounts(appAccounts: List<AssetAccount>) {
137+
scope.launch {
138+
runCatching {
139+
json.encodeToString<List<AssetAccount>>(appAccounts)
140+
}.getOrNull()?.let { accountsJson ->
141+
preferences.saveString(FlexaConstants.ASSET_ACCOUNTS, accountsJson)
142+
}
128143
}
129144
}
130145

core/src/main/java/com/flexa/core/shared/AssetAccount.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,51 @@ package com.flexa.core.shared
22

33
import android.graphics.Color
44

5+
import kotlinx.serialization.SerialName
6+
import kotlinx.serialization.Serializable
7+
8+
@Serializable
59
data class AssetAccount(
610
/**
711
* SHA256 hash of Account ID string
812
*/
13+
@SerialName("asset_account_hash")
914
val assetAccountHash: String,
15+
@SerialName("custody_model")
1016
val custodyModel: CustodyModel,
17+
@SerialName("display_name")
1118
val displayName: String? = null,
19+
@SerialName("icon")
1220
val icon: String? = null,
21+
@SerialName("available_assets")
1322
val availableAssets: List<AvailableAsset>,
1423
)
1524

25+
@Serializable
1626
data class AvailableAsset(
27+
@SerialName("asset_id")
1728
val assetId: String,
29+
@SerialName("balance")
1830
val balance: Double,
1931
/**
2032
* Due to the nature of the UTXO model used on Bitcoin and Zcash,
2133
* spendable balance can fluctuate, sometimes to zero temporarily
2234
* as the transaction is being mined and confirmed on-chain
2335
*/
36+
@SerialName("balance_available")
2437
val balanceAvailable: Double? = null,
38+
@SerialName("icon")
2539
val icon: String? = null,
40+
@SerialName("display_name")
2641
val displayName: String? = null,
42+
@SerialName("symbol")
2743
val symbol: String? = null,
44+
@SerialName("accent_color")
45+
@Serializable(with = ColorSerializer::class)
2846
val accentColor: Color? = null,
2947
)
3048

49+
@Serializable
3150
enum class CustodyModel {
3251
LOCAL, MANAGED
3352
}

core/src/main/java/com/flexa/core/shared/ConnectionHandler.kt

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import android.net.ConnectivityManager
55
import android.net.Network
66
import android.net.NetworkCapabilities
77
import android.net.NetworkRequest
8-
import android.os.Build
98
import androidx.compose.runtime.Composable
109
import androidx.compose.runtime.State
1110
import androidx.compose.runtime.mutableStateOf
@@ -22,7 +21,7 @@ sealed class ConnectionState {
2221
data object Unavailable : ConnectionState()
2322
}
2423

25-
val Context.currentConnectivityState: ConnectionState
24+
private val Context.currentConnectivityState: ConnectionState
2625
get() {
2726
val connectivityManager =
2827
getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
@@ -32,18 +31,10 @@ val Context.currentConnectivityState: ConnectionState
3231
private fun getCurrentConnectionState(
3332
connectivityManager: ConnectivityManager
3433
): ConnectionState {
34+
val network = connectivityManager.activeNetwork
35+
val actNetwork = runCatching { connectivityManager.getNetworkCapabilities(network) }
3536
val connected =
36-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
37-
val network = connectivityManager.activeNetwork
38-
val actNetwork = runCatching { connectivityManager.getNetworkCapabilities(network) }
39-
actNetwork.getOrNull()?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) == true
40-
} else {
41-
@Suppress("DEPRECATION")
42-
connectivityManager.allNetworks.any { network ->
43-
connectivityManager.getNetworkCapabilities(network)
44-
?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) == true
45-
}
46-
}
37+
actNetwork.getOrNull()?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) == true
4738
return if (connected) ConnectionState.Available else ConnectionState.Unavailable
4839
}
4940

@@ -56,19 +47,20 @@ fun Context.observeConnectionAsFlow() = callbackFlow {
5647
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
5748
.build()
5849
connectivityManager.registerNetworkCallback(networkRequest, callback)
59-
val currentState = getCurrentConnectionState(connectivityManager)
60-
trySend(currentState)
6150
awaitClose { connectivityManager.unregisterNetworkCallback(callback) }
6251
}
6352

53+
private val typesSet = HashSet<String>(2)
6454
fun networkCallback(callback: (ConnectionState) -> Unit): ConnectivityManager.NetworkCallback {
6555
return object : ConnectivityManager.NetworkCallback() {
6656
override fun onAvailable(network: Network) {
57+
typesSet.add(network.toString())
6758
callback(ConnectionState.Available)
6859
}
6960

7061
override fun onLost(network: Network) {
71-
callback(ConnectionState.Unavailable)
62+
typesSet.remove(network.toString())
63+
if (typesSet.isEmpty()) callback(ConnectionState.Unavailable)
7264
}
7365
}
7466
}

core/src/main/java/com/flexa/core/shared/FlexaConstants.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ class FlexaConstants {
66
const val RETRY_DELAY = 500L
77
const val RETRY_COUNT = 3
88
const val FILE = "flexa"
9-
const val ANDROID = "android"
109
const val PUBLISHABLE_KEY = "publishable.key"
1110
const val UNIQUE_IDENTIFIER = "unique.identifier"
1211
const val PLACES_TO_PAY_THEME = "places.to.pay.theme"
1312
const val VERIFIER = "verifier"
1413
const val TOKEN = "token"
1514
const val TOKEN_EXPIRATION = "token.expiration"
1615
const val APP_ACCOUNTS = "app.accounts"
16+
const val ASSET_ACCOUNTS = "asset.accounts"
1717
const val TOKEN_ID = "token.id"
1818
const val EMAIL = "email"
1919
const val EMPTY = ""

core/src/main/java/com/flexa/core/shared/SerializerProvider.kt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
package com.flexa.core.shared
22

3+
import android.graphics.Color
34
import com.google.gson.Gson
5+
import kotlinx.serialization.KSerializer
6+
import kotlinx.serialization.descriptors.PrimitiveKind
7+
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
8+
import kotlinx.serialization.descriptors.SerialDescriptor
9+
import kotlinx.serialization.encoding.Decoder
10+
import kotlinx.serialization.encoding.Encoder
411

512

613
class SerializerProvider {
@@ -10,3 +17,17 @@ class SerializerProvider {
1017
Gson()
1118
}
1219
}
20+
21+
object ColorSerializer : KSerializer<Color> {
22+
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("com.flexa.core.shared.Color", PrimitiveKind.INT)
23+
24+
override fun serialize(encoder: Encoder, value: Color) {
25+
val raw = value.toArgb()
26+
encoder.encodeInt(raw)
27+
}
28+
29+
override fun deserialize(decoder: Decoder): Color {
30+
val raw = decoder.decodeInt()
31+
return Color.valueOf(raw)
32+
}
33+
}

0 commit comments

Comments
 (0)