Skip to content

Commit 9161753

Browse files
Merge pull request #88 from Web3Auth/feat/config_api
Feat/config api
2 parents d3e77af + c3d31d1 commit 9161753

File tree

11 files changed

+261
-31
lines changed

11 files changed

+261
-31
lines changed

app/src/main/java/com/web3auth/app/MainActivity.kt

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,37 @@ import android.os.Bundle
66
import android.text.method.ScrollingMovementMethod
77
import android.util.Log
88
import android.view.View
9-
import android.widget.*
9+
import android.widget.AdapterView
10+
import android.widget.ArrayAdapter
11+
import android.widget.AutoCompleteTextView
12+
import android.widget.Button
13+
import android.widget.EditText
14+
import android.widget.TextView
15+
import android.widget.Toast
1016
import androidx.appcompat.app.AlertDialog
1117
import androidx.appcompat.app.AppCompatActivity
1218
import com.google.android.material.textfield.TextInputLayout
1319
import com.google.gson.Gson
1420
import com.google.gson.JsonArray
1521
import com.web3auth.core.Web3Auth
1622
import com.web3auth.core.isEmailValid
17-
import com.web3auth.core.types.*
23+
import com.web3auth.core.isPhoneNumberValid
24+
import com.web3auth.core.types.BuildEnv
25+
import com.web3auth.core.types.ChainConfig
26+
import com.web3auth.core.types.ChainNamespace
27+
import com.web3auth.core.types.ExtraLoginOptions
28+
import com.web3auth.core.types.Language
29+
import com.web3auth.core.types.LoginConfigItem
30+
import com.web3auth.core.types.LoginParams
31+
import com.web3auth.core.types.MFALevel
32+
import com.web3auth.core.types.Network
33+
import com.web3auth.core.types.Provider
34+
import com.web3auth.core.types.ThemeModes
35+
import com.web3auth.core.types.TypeOfLogin
36+
import com.web3auth.core.types.UserInfo
37+
import com.web3auth.core.types.Web3AuthOptions
38+
import com.web3auth.core.types.Web3AuthResponse
39+
import com.web3auth.core.types.WhiteLabelData
1840
import org.json.JSONObject
1941
import org.web3j.crypto.Credentials
2042
import java.util.concurrent.CompletableFuture
@@ -36,7 +58,10 @@ class MainActivity : AppCompatActivity(), AdapterView.OnItemClickListener {
3658
LoginVerifier("LinkedIn", Provider.LINKEDIN),
3759
LoginVerifier("Twitter", Provider.TWITTER),
3860
LoginVerifier("Line", Provider.LINE),
39-
LoginVerifier("Hosted Email Passwordless", Provider.EMAIL_PASSWORDLESS)
61+
LoginVerifier("Hosted Email Passwordless", Provider.EMAIL_PASSWORDLESS),
62+
LoginVerifier("SMS Passwordless", Provider.SMS_PASSWORDLESS),
63+
LoginVerifier("JWT", Provider.JWT),
64+
LoginVerifier("Farcaster", Provider.FARCASTER)
4065
)
4166

4267
private var selectedLoginProvider: Provider = Provider.GOOGLE
@@ -54,6 +79,16 @@ class MainActivity : AppCompatActivity(), AdapterView.OnItemClickListener {
5479
}
5580
extraLoginOptions = ExtraLoginOptions(login_hint = hintEmail)
5681
}
82+
83+
if (selectedLoginProvider == Provider.SMS_PASSWORDLESS) {
84+
val hintPhNo = hintEmailEditText.text.toString()
85+
if (hintPhNo.isBlank() || !hintPhNo.isPhoneNumberValid()) {
86+
Toast.makeText(this, "Please enter a valid Number.", Toast.LENGTH_LONG).show()
87+
return
88+
}
89+
extraLoginOptions = ExtraLoginOptions(login_hint = hintPhNo)
90+
}
91+
5792
val loginCompletableFuture: CompletableFuture<Web3AuthResponse> = web3Auth.login(
5893
LoginParams(
5994
selectedLoginProvider,
@@ -132,7 +167,7 @@ class MainActivity : AppCompatActivity(), AdapterView.OnItemClickListener {
132167

133168
val options = Web3AuthOptions(
134169
context = this,
135-
clientId = "BHgArYmWwSeq21czpcarYh0EVq2WWOzflX-NTK-tY1-1pauPzHKRRLgpABkmYiIV_og9jAvoIxQ8L3Smrwe04Lw",
170+
clientId = "BFuUqebV5I8Pz5F7a5A2ihW7YVmbv_OHXnHYDv6OltAD5NGr6e-ViNvde3U4BHdn6HvwfkgobhVu4VwC-OSJkik",
136171
network = Network.SAPPHIRE_DEVNET,
137172
redirectUrl = Uri.parse("torusapp://org.torusresearch.web3authexample"),
138173
// sdkUrl = "https://auth.mocaverse.xyz",
@@ -141,14 +176,15 @@ class MainActivity : AppCompatActivity(), AdapterView.OnItemClickListener {
141176
"Web3Auth Sample App", null, null, null,
142177
Language.EN, ThemeModes.LIGHT, true,
143178
hashMapOf(
144-
"primary" to "#123456"
179+
"primary" to "#123456",
180+
"onPrimary" to "#0000FF"
145181
)
146182
),
147183
loginConfig = hashMapOf(
148184
"loginConfig" to LoginConfigItem(
149185
"web3auth-auth0-email-passwordless-sapphire-devnet",
150186
typeOfLogin = TypeOfLogin.JWT,
151-
clientId = "d84f6xvbdV75VTGmHiMWfZLeSPk8M07C"
187+
clientId = "d84f6xvbdV75VTGmHiMWfZLeSPk8M07C",
152188
)
153189
),
154190
buildEnv = BuildEnv.TESTING,
@@ -283,7 +319,14 @@ class MainActivity : AppCompatActivity(), AdapterView.OnItemClickListener {
283319
selectedLoginProvider = verifierList[p2].loginProvider
284320

285321
val hintEmailEditText = findViewById<EditText>(R.id.etEmailHint)
322+
286323
if (selectedLoginProvider == Provider.EMAIL_PASSWORDLESS) {
324+
hintEmailEditText.hint = "Enter Email"
325+
} else if (selectedLoginProvider == Provider.SMS_PASSWORDLESS) {
326+
hintEmailEditText.hint = "Enter Phone Number"
327+
}
328+
329+
if (selectedLoginProvider == Provider.EMAIL_PASSWORDLESS || selectedLoginProvider == Provider.SMS_PASSWORDLESS) {
287330
hintEmailEditText.visibility = View.VISIBLE
288331
} else {
289332
hintEmailEditText.visibility = View.GONE

core/src/main/java/com/web3auth/core/Utils.kt

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import android.net.Uri
77
import android.util.Base64
88
import android.util.Patterns
99
import androidx.browser.customtabs.CustomTabsService
10+
import com.web3auth.core.types.WhiteLabelData
1011

1112
const val BASE64_URL_FLAGS = Base64.URL_SAFE or Base64.NO_WRAP or Base64.NO_PADDING
1213

@@ -41,6 +42,10 @@ fun String.isEmailValid(): Boolean {
4142
return Patterns.EMAIL_ADDRESS.matcher(this).matches()
4243
}
4344

45+
fun String.isPhoneNumberValid(): Boolean {
46+
return Patterns.PHONE.matcher(this).matches()
47+
}
48+
4449
fun Context.getDefaultBrowser(): String? {
4550
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://web3auth.io"))
4651
val resolveInfo = packageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY)
@@ -62,4 +67,49 @@ fun Context.getCustomTabsBrowsers(): List<String> {
6267
}
6368
}
6469
return customTabsBrowsers
65-
}
70+
}
71+
72+
fun WhiteLabelData.merge(other: WhiteLabelData): WhiteLabelData {
73+
val mergedTheme = HashMap<String, String?>()
74+
this.theme.let {
75+
if (it != null) {
76+
mergedTheme.putAll(it)
77+
}
78+
}
79+
other.theme?.forEach { (key, value) ->
80+
if (!mergedTheme.containsKey(key)) {
81+
mergedTheme[key] = value ?: mergedTheme[key]
82+
}
83+
}
84+
85+
return WhiteLabelData(
86+
appName = this.appName ?: other.appName,
87+
appUrl = this.appUrl ?: other.appUrl,
88+
logoLight = this.logoLight ?: other.logoLight,
89+
logoDark = this.logoDark ?: other.logoDark,
90+
defaultLanguage = this.defaultLanguage ?: other.defaultLanguage,
91+
mode = this.mode ?: other.mode,
92+
useLogoLoader = this.useLogoLoader ?: other.useLogoLoader,
93+
theme = mergedTheme
94+
)
95+
}
96+
97+
fun Map<String, String>?.mergeMaps(other: Map<String, String>?): Map<String, String>? {
98+
if (this == null && other == null) {
99+
return null
100+
} else if (this == null) {
101+
return other
102+
} else if (other == null) {
103+
return this
104+
}
105+
106+
val mergedMap = LinkedHashMap<String, String>()
107+
mergedMap.putAll(this)
108+
109+
other.forEach { (key, value) ->
110+
mergedMap[key] = value
111+
}
112+
113+
return mergedMap
114+
}
115+

core/src/main/java/com/web3auth/core/Web3Auth.kt

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@ import com.google.gson.GsonBuilder
77
import com.google.gson.JsonArray
88
import com.google.gson.JsonObject
99
import com.web3auth.core.api.ApiHelper
10+
import com.web3auth.core.api.ApiService
1011
import com.web3auth.core.keystore.KeyStoreManagerUtils
1112
import com.web3auth.core.types.*
1213
import com.web3auth.session_manager_android.SessionManager
14+
import kotlinx.coroutines.GlobalScope
15+
import kotlinx.coroutines.launch
1316
import org.json.JSONObject
1417
import java.util.*
1518
import java.util.concurrent.CompletableFuture
@@ -54,6 +57,9 @@ class Web3Auth(web3AuthOptions: Web3AuthOptions) {
5457
if (web3AuthOption.sessionTime != null) initOptions.put(
5558
"sessionTime", web3AuthOption.sessionTime
5659
)
60+
if (web3AuthOption.originData != null) initOptions.put(
61+
"originData", gson.toJson(web3AuthOption.originData)
62+
)
5763
return initOptions
5864
}
5965

@@ -167,6 +173,10 @@ class Web3Auth(web3AuthOptions: Web3AuthOptions) {
167173

168174
//authorize session
169175
if (ApiHelper.isNetworkAvailable(web3AuthOption.context)) {
176+
177+
//fetch project config
178+
fetchProjectConfig()
179+
170180
this.authorizeSession().whenComplete { resp, error ->
171181
if (error == null) {
172182
web3AuthResponse = resp
@@ -367,6 +377,51 @@ class Web3Auth(web3AuthOptions: Web3AuthOptions) {
367377
return sessionCompletableFuture
368378
}
369379

380+
private fun fetchProjectConfig() {
381+
val projectConfigCompletableFuture: CompletableFuture<ProjectConfigResponse> =
382+
CompletableFuture()
383+
val web3AuthApi =
384+
ApiHelper.getInstance(web3AuthOption.network.name).create(ApiService::class.java)
385+
GlobalScope.launch {
386+
try {
387+
val result = web3AuthApi.fetchProjectConfig(
388+
web3AuthOption.clientId,
389+
web3AuthOption.network.name
390+
)
391+
if (result.isSuccessful && result.body() != null) {
392+
val response = result.body()
393+
web3AuthOption.originData =
394+
web3AuthOption.originData.mergeMaps(response?.whitelist?.signed_urls)
395+
if (response?.whitelabel != null) {
396+
if(web3AuthOption.whiteLabel == null) {
397+
web3AuthOption.whiteLabel = response.whitelabel
398+
} else {
399+
web3AuthOption.whiteLabel =
400+
web3AuthOption.whiteLabel!!.merge(response.whitelabel)
401+
}
402+
}
403+
} else {
404+
projectConfigCompletableFuture.completeExceptionally(
405+
Exception(
406+
Web3AuthError.getError(
407+
ErrorCode.RUNTIME_ERROR
408+
)
409+
)
410+
)
411+
}
412+
} catch (ex: Exception) {
413+
ex.printStackTrace()
414+
projectConfigCompletableFuture.completeExceptionally(
415+
Exception(
416+
Web3AuthError.getError(
417+
ErrorCode.SOMETHING_WENT_WRONG
418+
)
419+
)
420+
)
421+
}
422+
}
423+
}
424+
370425
/**
371426
* Retrieves the login ID from the provided JSONObject asynchronously.
372427
*

core/src/main/java/com/web3auth/core/api/ApiHelper.kt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,47 @@ import android.content.Context
44
import android.net.ConnectivityManager
55
import android.net.NetworkCapabilities
66
import android.os.Build
7+
import com.google.gson.GsonBuilder
8+
import com.web3auth.core.types.Network
9+
import com.web3auth.session_manager_android.BuildConfig
10+
import okhttp3.OkHttpClient
11+
import okhttp3.logging.HttpLoggingInterceptor
12+
import retrofit2.Retrofit
13+
import retrofit2.converter.gson.GsonConverterFactory
14+
import java.util.concurrent.TimeUnit
715

816
object ApiHelper {
917

18+
val SIGNER_MAP: Map<Network, String> = mapOf(
19+
Network.MAINNET to "https://signer.web3auth.io",
20+
Network.TESTNET to "https://signer.web3auth.io",
21+
Network.CYAN to "https://signer-polygon.web3auth.io",
22+
Network.AQUA to "https://signer-polygon.web3auth.io",
23+
Network.SAPPHIRE_MAINNET to "https://signer.web3auth.io",
24+
Network.SAPPHIRE_DEVNET to "https://signer.web3auth.io"
25+
)
26+
27+
private const val sessionBaseUrl = "https://session.web3auth.io"
28+
29+
private val okHttpClient = OkHttpClient().newBuilder()
30+
.readTimeout(60, TimeUnit.SECONDS)
31+
.connectTimeout(20, TimeUnit.SECONDS)
32+
.addInterceptor(HttpLoggingInterceptor().apply {
33+
if (BuildConfig.DEBUG) {
34+
level = HttpLoggingInterceptor.Level.BODY
35+
}
36+
})
37+
.build()
38+
39+
private val builder = GsonBuilder().disableHtmlEscaping().create()
40+
41+
fun getInstance(network: String): Retrofit {
42+
return Retrofit.Builder().baseUrl(SIGNER_MAP[Network.valueOf(network)])
43+
.addConverterFactory(GsonConverterFactory.create(builder))
44+
.client(okHttpClient)
45+
.build()
46+
}
47+
1048
fun isNetworkAvailable(context: Context?): Boolean {
1149
if (context == null) return false
1250
val connectivityManager =
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.web3auth.core.api
2+
3+
import com.web3auth.core.types.ProjectConfigResponse
4+
import retrofit2.Response
5+
import retrofit2.http.GET
6+
import retrofit2.http.Query
7+
8+
interface ApiService {
9+
10+
@GET("/api/configuration")
11+
suspend fun fetchProjectConfig(
12+
@Query("project_id") project_id: String, @Query("network") network: String,
13+
@Query("whitelist") whitelist: String = "true"
14+
): Response<ProjectConfigResponse>
15+
}

core/src/main/java/com/web3auth/core/types/LoginConfigItem.kt

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@ package com.web3auth.core.types
22

33
data class LoginConfigItem(
44
var verifier: String,
5-
private var typeOfLogin: TypeOfLogin,
6-
private var name: String? = null,
7-
private var description: String? = null,
8-
private var clientId: String,
9-
private var verifierSubIdentifier: String? = null,
10-
private var logoHover: String? = null,
11-
private var logoLight: String? = null,
12-
private var logoDark: String? = null,
13-
private var mainOption: Boolean? = false,
14-
private var showOnModal: Boolean? = true,
15-
private var showOnDesktop: Boolean? = true,
16-
private var showOnMobile: Boolean? = true,
5+
var typeOfLogin: TypeOfLogin,
6+
var name: String? = null,
7+
var description: String? = null,
8+
var clientId: String,
9+
var verifierSubIdentifier: String? = null,
10+
var logoHover: String? = null,
11+
var logoLight: String? = null,
12+
var logoDark: String? = null,
13+
var mainOption: Boolean? = false,
14+
var showOnModal: Boolean? = true,
15+
var showOnDesktop: Boolean? = true,
16+
var showOnMobile: Boolean? = true,
1717
)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.web3auth.core.types
2+
3+
import androidx.annotation.Keep
4+
5+
@Keep
6+
data class WhitelistResponse(
7+
val urls: List<String>,
8+
val signed_urls: Map<String, String>
9+
)
10+
11+
@Keep
12+
data class ProjectConfigResponse(
13+
val whitelabel: WhiteLabelData? = null,
14+
val sms_otp_enabled: Boolean,
15+
val wallet_connect_enabled: Boolean,
16+
val wallet_connect_project_id: String?,
17+
val whitelist: WhitelistResponse?,
18+
)

core/src/main/java/com/web3auth/core/types/Provider.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ enum class Provider {
2121
GITHUB,
2222
@SerializedName("kakao")
2323
KAKAO,
24+
2425
@SerializedName("linkedin")
2526
LINKEDIN,
2627

0 commit comments

Comments
 (0)