Skip to content

Commit

Permalink
Merge pull request #88 from Web3Auth/feat/config_api
Browse files Browse the repository at this point in the history
Feat/config api
  • Loading branch information
chaitanyapotti authored Jun 10, 2024
2 parents d3e77af + c3d31d1 commit 9161753
Show file tree
Hide file tree
Showing 11 changed files with 261 additions and 31 deletions.
55 changes: 49 additions & 6 deletions app/src/main/java/com/web3auth/app/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,37 @@ import android.os.Bundle
import android.text.method.ScrollingMovementMethod
import android.util.Log
import android.view.View
import android.widget.*
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.AutoCompleteTextView
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.textfield.TextInputLayout
import com.google.gson.Gson
import com.google.gson.JsonArray
import com.web3auth.core.Web3Auth
import com.web3auth.core.isEmailValid
import com.web3auth.core.types.*
import com.web3auth.core.isPhoneNumberValid
import com.web3auth.core.types.BuildEnv
import com.web3auth.core.types.ChainConfig
import com.web3auth.core.types.ChainNamespace
import com.web3auth.core.types.ExtraLoginOptions
import com.web3auth.core.types.Language
import com.web3auth.core.types.LoginConfigItem
import com.web3auth.core.types.LoginParams
import com.web3auth.core.types.MFALevel
import com.web3auth.core.types.Network
import com.web3auth.core.types.Provider
import com.web3auth.core.types.ThemeModes
import com.web3auth.core.types.TypeOfLogin
import com.web3auth.core.types.UserInfo
import com.web3auth.core.types.Web3AuthOptions
import com.web3auth.core.types.Web3AuthResponse
import com.web3auth.core.types.WhiteLabelData
import org.json.JSONObject
import org.web3j.crypto.Credentials
import java.util.concurrent.CompletableFuture
Expand All @@ -36,7 +58,10 @@ class MainActivity : AppCompatActivity(), AdapterView.OnItemClickListener {
LoginVerifier("LinkedIn", Provider.LINKEDIN),
LoginVerifier("Twitter", Provider.TWITTER),
LoginVerifier("Line", Provider.LINE),
LoginVerifier("Hosted Email Passwordless", Provider.EMAIL_PASSWORDLESS)
LoginVerifier("Hosted Email Passwordless", Provider.EMAIL_PASSWORDLESS),
LoginVerifier("SMS Passwordless", Provider.SMS_PASSWORDLESS),
LoginVerifier("JWT", Provider.JWT),
LoginVerifier("Farcaster", Provider.FARCASTER)
)

private var selectedLoginProvider: Provider = Provider.GOOGLE
Expand All @@ -54,6 +79,16 @@ class MainActivity : AppCompatActivity(), AdapterView.OnItemClickListener {
}
extraLoginOptions = ExtraLoginOptions(login_hint = hintEmail)
}

if (selectedLoginProvider == Provider.SMS_PASSWORDLESS) {
val hintPhNo = hintEmailEditText.text.toString()
if (hintPhNo.isBlank() || !hintPhNo.isPhoneNumberValid()) {
Toast.makeText(this, "Please enter a valid Number.", Toast.LENGTH_LONG).show()
return
}
extraLoginOptions = ExtraLoginOptions(login_hint = hintPhNo)
}

val loginCompletableFuture: CompletableFuture<Web3AuthResponse> = web3Auth.login(
LoginParams(
selectedLoginProvider,
Expand Down Expand Up @@ -132,7 +167,7 @@ class MainActivity : AppCompatActivity(), AdapterView.OnItemClickListener {

val options = Web3AuthOptions(
context = this,
clientId = "BHgArYmWwSeq21czpcarYh0EVq2WWOzflX-NTK-tY1-1pauPzHKRRLgpABkmYiIV_og9jAvoIxQ8L3Smrwe04Lw",
clientId = "BFuUqebV5I8Pz5F7a5A2ihW7YVmbv_OHXnHYDv6OltAD5NGr6e-ViNvde3U4BHdn6HvwfkgobhVu4VwC-OSJkik",
network = Network.SAPPHIRE_DEVNET,
redirectUrl = Uri.parse("torusapp://org.torusresearch.web3authexample"),
// sdkUrl = "https://auth.mocaverse.xyz",
Expand All @@ -141,14 +176,15 @@ class MainActivity : AppCompatActivity(), AdapterView.OnItemClickListener {
"Web3Auth Sample App", null, null, null,
Language.EN, ThemeModes.LIGHT, true,
hashMapOf(
"primary" to "#123456"
"primary" to "#123456",
"onPrimary" to "#0000FF"
)
),
loginConfig = hashMapOf(
"loginConfig" to LoginConfigItem(
"web3auth-auth0-email-passwordless-sapphire-devnet",
typeOfLogin = TypeOfLogin.JWT,
clientId = "d84f6xvbdV75VTGmHiMWfZLeSPk8M07C"
clientId = "d84f6xvbdV75VTGmHiMWfZLeSPk8M07C",
)
),
buildEnv = BuildEnv.TESTING,
Expand Down Expand Up @@ -283,7 +319,14 @@ class MainActivity : AppCompatActivity(), AdapterView.OnItemClickListener {
selectedLoginProvider = verifierList[p2].loginProvider

val hintEmailEditText = findViewById<EditText>(R.id.etEmailHint)

if (selectedLoginProvider == Provider.EMAIL_PASSWORDLESS) {
hintEmailEditText.hint = "Enter Email"
} else if (selectedLoginProvider == Provider.SMS_PASSWORDLESS) {
hintEmailEditText.hint = "Enter Phone Number"
}

if (selectedLoginProvider == Provider.EMAIL_PASSWORDLESS || selectedLoginProvider == Provider.SMS_PASSWORDLESS) {
hintEmailEditText.visibility = View.VISIBLE
} else {
hintEmailEditText.visibility = View.GONE
Expand Down
52 changes: 51 additions & 1 deletion core/src/main/java/com/web3auth/core/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import android.net.Uri
import android.util.Base64
import android.util.Patterns
import androidx.browser.customtabs.CustomTabsService
import com.web3auth.core.types.WhiteLabelData

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

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

fun String.isPhoneNumberValid(): Boolean {
return Patterns.PHONE.matcher(this).matches()
}

fun Context.getDefaultBrowser(): String? {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://web3auth.io"))
val resolveInfo = packageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY)
Expand All @@ -62,4 +67,49 @@ fun Context.getCustomTabsBrowsers(): List<String> {
}
}
return customTabsBrowsers
}
}

fun WhiteLabelData.merge(other: WhiteLabelData): WhiteLabelData {
val mergedTheme = HashMap<String, String?>()
this.theme.let {
if (it != null) {
mergedTheme.putAll(it)
}
}
other.theme?.forEach { (key, value) ->
if (!mergedTheme.containsKey(key)) {
mergedTheme[key] = value ?: mergedTheme[key]
}
}

return WhiteLabelData(
appName = this.appName ?: other.appName,
appUrl = this.appUrl ?: other.appUrl,
logoLight = this.logoLight ?: other.logoLight,
logoDark = this.logoDark ?: other.logoDark,
defaultLanguage = this.defaultLanguage ?: other.defaultLanguage,
mode = this.mode ?: other.mode,
useLogoLoader = this.useLogoLoader ?: other.useLogoLoader,
theme = mergedTheme
)
}

fun Map<String, String>?.mergeMaps(other: Map<String, String>?): Map<String, String>? {
if (this == null && other == null) {
return null
} else if (this == null) {
return other
} else if (other == null) {
return this
}

val mergedMap = LinkedHashMap<String, String>()
mergedMap.putAll(this)

other.forEach { (key, value) ->
mergedMap[key] = value
}

return mergedMap
}

55 changes: 55 additions & 0 deletions core/src/main/java/com/web3auth/core/Web3Auth.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ import com.google.gson.GsonBuilder
import com.google.gson.JsonArray
import com.google.gson.JsonObject
import com.web3auth.core.api.ApiHelper
import com.web3auth.core.api.ApiService
import com.web3auth.core.keystore.KeyStoreManagerUtils
import com.web3auth.core.types.*
import com.web3auth.session_manager_android.SessionManager
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.json.JSONObject
import java.util.*
import java.util.concurrent.CompletableFuture
Expand Down Expand Up @@ -54,6 +57,9 @@ class Web3Auth(web3AuthOptions: Web3AuthOptions) {
if (web3AuthOption.sessionTime != null) initOptions.put(
"sessionTime", web3AuthOption.sessionTime
)
if (web3AuthOption.originData != null) initOptions.put(
"originData", gson.toJson(web3AuthOption.originData)
)
return initOptions
}

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

//authorize session
if (ApiHelper.isNetworkAvailable(web3AuthOption.context)) {

//fetch project config
fetchProjectConfig()

this.authorizeSession().whenComplete { resp, error ->
if (error == null) {
web3AuthResponse = resp
Expand Down Expand Up @@ -367,6 +377,51 @@ class Web3Auth(web3AuthOptions: Web3AuthOptions) {
return sessionCompletableFuture
}

private fun fetchProjectConfig() {
val projectConfigCompletableFuture: CompletableFuture<ProjectConfigResponse> =
CompletableFuture()
val web3AuthApi =
ApiHelper.getInstance(web3AuthOption.network.name).create(ApiService::class.java)
GlobalScope.launch {
try {
val result = web3AuthApi.fetchProjectConfig(
web3AuthOption.clientId,
web3AuthOption.network.name
)
if (result.isSuccessful && result.body() != null) {
val response = result.body()
web3AuthOption.originData =
web3AuthOption.originData.mergeMaps(response?.whitelist?.signed_urls)
if (response?.whitelabel != null) {
if(web3AuthOption.whiteLabel == null) {
web3AuthOption.whiteLabel = response.whitelabel
} else {
web3AuthOption.whiteLabel =
web3AuthOption.whiteLabel!!.merge(response.whitelabel)
}
}
} else {
projectConfigCompletableFuture.completeExceptionally(
Exception(
Web3AuthError.getError(
ErrorCode.RUNTIME_ERROR
)
)
)
}
} catch (ex: Exception) {
ex.printStackTrace()
projectConfigCompletableFuture.completeExceptionally(
Exception(
Web3AuthError.getError(
ErrorCode.SOMETHING_WENT_WRONG
)
)
)
}
}
}

/**
* Retrieves the login ID from the provided JSONObject asynchronously.
*
Expand Down
38 changes: 38 additions & 0 deletions core/src/main/java/com/web3auth/core/api/ApiHelper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,47 @@ import android.content.Context
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.os.Build
import com.google.gson.GsonBuilder
import com.web3auth.core.types.Network
import com.web3auth.session_manager_android.BuildConfig
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit

object ApiHelper {

val SIGNER_MAP: Map<Network, String> = mapOf(
Network.MAINNET to "https://signer.web3auth.io",
Network.TESTNET to "https://signer.web3auth.io",
Network.CYAN to "https://signer-polygon.web3auth.io",
Network.AQUA to "https://signer-polygon.web3auth.io",
Network.SAPPHIRE_MAINNET to "https://signer.web3auth.io",
Network.SAPPHIRE_DEVNET to "https://signer.web3auth.io"
)

private const val sessionBaseUrl = "https://session.web3auth.io"

private val okHttpClient = OkHttpClient().newBuilder()
.readTimeout(60, TimeUnit.SECONDS)
.connectTimeout(20, TimeUnit.SECONDS)
.addInterceptor(HttpLoggingInterceptor().apply {
if (BuildConfig.DEBUG) {
level = HttpLoggingInterceptor.Level.BODY
}
})
.build()

private val builder = GsonBuilder().disableHtmlEscaping().create()

fun getInstance(network: String): Retrofit {
return Retrofit.Builder().baseUrl(SIGNER_MAP[Network.valueOf(network)])
.addConverterFactory(GsonConverterFactory.create(builder))
.client(okHttpClient)
.build()
}

fun isNetworkAvailable(context: Context?): Boolean {
if (context == null) return false
val connectivityManager =
Expand Down
15 changes: 15 additions & 0 deletions core/src/main/java/com/web3auth/core/api/ApiService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.web3auth.core.api

import com.web3auth.core.types.ProjectConfigResponse
import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Query

interface ApiService {

@GET("/api/configuration")
suspend fun fetchProjectConfig(
@Query("project_id") project_id: String, @Query("network") network: String,
@Query("whitelist") whitelist: String = "true"
): Response<ProjectConfigResponse>
}
24 changes: 12 additions & 12 deletions core/src/main/java/com/web3auth/core/types/LoginConfigItem.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ package com.web3auth.core.types

data class LoginConfigItem(
var verifier: String,
private var typeOfLogin: TypeOfLogin,
private var name: String? = null,
private var description: String? = null,
private var clientId: String,
private var verifierSubIdentifier: String? = null,
private var logoHover: String? = null,
private var logoLight: String? = null,
private var logoDark: String? = null,
private var mainOption: Boolean? = false,
private var showOnModal: Boolean? = true,
private var showOnDesktop: Boolean? = true,
private var showOnMobile: Boolean? = true,
var typeOfLogin: TypeOfLogin,
var name: String? = null,
var description: String? = null,
var clientId: String,
var verifierSubIdentifier: String? = null,
var logoHover: String? = null,
var logoLight: String? = null,
var logoDark: String? = null,
var mainOption: Boolean? = false,
var showOnModal: Boolean? = true,
var showOnDesktop: Boolean? = true,
var showOnMobile: Boolean? = true,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.web3auth.core.types

import androidx.annotation.Keep

@Keep
data class WhitelistResponse(
val urls: List<String>,
val signed_urls: Map<String, String>
)

@Keep
data class ProjectConfigResponse(
val whitelabel: WhiteLabelData? = null,
val sms_otp_enabled: Boolean,
val wallet_connect_enabled: Boolean,
val wallet_connect_project_id: String?,
val whitelist: WhitelistResponse?,
)
1 change: 1 addition & 0 deletions core/src/main/java/com/web3auth/core/types/Provider.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ enum class Provider {
GITHUB,
@SerializedName("kakao")
KAKAO,

@SerializedName("linkedin")
LINKEDIN,

Expand Down
Loading

0 comments on commit 9161753

Please sign in to comment.