Skip to content

Commit

Permalink
Support to SD-JWT credentials (#29)
Browse files Browse the repository at this point in the history
* Add templates and prepare to integrations

* Configure raw credential storage and start adding/listing

* Display credential info

* Bump mobile-sdk-rs version

* Integrate decodeSdJwt method

* Update name and logo

* Update app name
  • Loading branch information
Juliano1612 authored Sep 26, 2024
1 parent ba478c8 commit fd8bff6
Show file tree
Hide file tree
Showing 43 changed files with 837 additions and 321 deletions.
2 changes: 1 addition & 1 deletion MobileSdk/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ android {
}

dependencies {
api("com.spruceid.mobile.sdk.rs:mobilesdkrs:0.0.30")
api("com.spruceid.mobile.sdk.rs:mobilesdkrs:0.0.31")
//noinspection GradleCompatible
implementation("com.android.support:appcompat-v7:28.0.0")
/* Begin UI dependencies */
Expand Down
4 changes: 2 additions & 2 deletions MobileSdk/src/main/java/com/spruceid/mobile/sdk/MDoc.kt
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package com.spruceid.mobile.sdk

import android.util.Log
import com.spruceid.mobile.sdk.rs.MDoc as InnerMDoc
import com.spruceid.mobile.sdk.rs.Mdoc as InnerMDoc

class MDoc(id: String, issuerAuth: ByteArray, val keyAlias: String) : BaseCredential(id) {
val inner: InnerMDoc

init {
try {
inner = InnerMDoc.fromCbor(issuerAuth)
inner = InnerMDoc.fromCborEncodedDocument(issuerAuth, keyAlias)
} catch (e: Throwable) {
Log.e("MDoc.init", e.toString())
throw e
Expand Down
10 changes: 10 additions & 0 deletions example/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@


<application
android:name=".MainApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
Expand All @@ -39,6 +40,15 @@

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<!-- Intent action and categories -->
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Deep link data -->
<data android:scheme="spruceid" />
<data android:scheme="openid4vp" />
</intent-filter>
</activity>
</application>

Expand Down
Binary file added example/src/main/ic_launcher-playstore.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 9 additions & 3 deletions example/src/main/java/com/spruceid/mobilesdkexample/HomeView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import com.spruceid.mobilesdkexample.ui.theme.Bg
import com.spruceid.mobilesdkexample.ui.theme.Inter
import com.spruceid.mobilesdkexample.ui.theme.MobileSdkTheme
import com.spruceid.mobilesdkexample.verifier.VerifierHomeView
import com.spruceid.mobilesdkexample.viewmodels.IRawCredentialsViewModel
import com.spruceid.mobilesdkexample.viewmodels.RawCredentialsViewModelPreview
import com.spruceid.mobilesdkexample.wallet.WalletHomeView

enum class HomeTabs {
Expand All @@ -39,7 +41,8 @@ enum class HomeTabs {
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
@Composable
fun HomeView(
navController: NavController
navController: NavController,
rawCredentialsViewModel: IRawCredentialsViewModel
) {
var tab by remember {
mutableStateOf(HomeTabs.WALLET)
Expand Down Expand Up @@ -88,7 +91,10 @@ fun HomeView(
) {
Box(modifier = Modifier.padding(bottom = 30.dp)) {
if (tab == HomeTabs.WALLET) {
WalletHomeView()
WalletHomeView(
navController,
rawCredentialsViewModel
)
} else {
VerifierHomeView(navController = navController)
}
Expand All @@ -101,6 +107,6 @@ fun HomeView(
fun HomeViewPreview() {
var navController: NavHostController = rememberNavController()
MobileSdkTheme {
HomeView(navController)
HomeView(navController, RawCredentialsViewModelPreview())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,19 @@ import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Surface
import androidx.compose.ui.Modifier
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import com.spruceid.mobilesdkexample.db.AppDatabase
import com.spruceid.mobilesdkexample.db.VerificationActivityLogsRepository
import com.spruceid.mobilesdkexample.db.RawCredentialsRepository
import com.spruceid.mobilesdkexample.navigation.SetupNavGraph
import com.spruceid.mobilesdkexample.ui.theme.Bg
import com.spruceid.mobilesdkexample.ui.theme.MobileSdkTheme
import com.spruceid.mobilesdkexample.viewmodels.IRawCredentialsViewModel
import com.spruceid.mobilesdkexample.viewmodels.RawCredentialsViewModelFactory

class MainActivity : ComponentActivity() {
private lateinit var navController: NavHostController
Expand All @@ -38,9 +41,17 @@ class MainActivity : ComponentActivity() {
) {
navController = rememberNavController()

SetupNavGraph(navController = navController)
val credentialsViewModel: IRawCredentialsViewModel by viewModels {
RawCredentialsViewModelFactory((application as MainApplication).rawCredentialsRepository)
}
SetupNavGraph(navController, credentialsViewModel)
}
}
}
}
}

class MainApplication : Application() {
val db by lazy { AppDatabase.getDatabase(applicationContext) }
val rawCredentialsRepository by lazy { RawCredentialsRepository(db.rawCredentialsDao()) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,17 @@ import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.TypeConverters

@Database(entities = [VerificationActivityLogs::class], version = 1)
@Database(
entities = [
VerificationActivityLogs::class,
RawCredentials::class,
],
version = 2
)
@TypeConverters(*[DateConverter::class])
abstract class AppDatabase : RoomDatabase() {
abstract fun verificationActivityLogsDao(): VerificationActivityLogsDao
abstract fun rawCredentialsDao(): RawCredentialsDao

companion object {
@Volatile
Expand All @@ -21,7 +28,7 @@ abstract class AppDatabase : RoomDatabase() {
Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
"verification_activity_logs",
"referenceAppDb",
)
.allowMainThreadQueries()
.build()
Expand Down
12 changes: 12 additions & 0 deletions example/src/main/java/com/spruceid/mobilesdkexample/db/Daos.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,15 @@ interface VerificationActivityLogsDao {
@Query("SELECT * FROM verification_activity_logs")
fun getAllVerificationActivityLogs(): List<VerificationActivityLogs>
}

@Dao
interface RawCredentialsDao {
@Insert
suspend fun insertRawCredential(rawCredential: RawCredentials)

@Query("SELECT * FROM raw_credentials")
fun getAllRawCredentials(): List<RawCredentials>

@Query("DELETE FROM raw_credentials")
fun deleteAllRawCredentials(): Int
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,9 @@ data class VerificationActivityLogs(
val expirationDate: Date,
val status: String,
)

@Entity(tableName = "raw_credentials")
data class RawCredentials(
@PrimaryKey(autoGenerate = true) val id: Long = 0,
val rawCredential: String,
)
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,22 @@ class VerificationActivityLogsRepository(private val verificationActivityLogsDao
return verificationActivityLogsDao.getAllVerificationActivityLogs()
}
}

class RawCredentialsRepository(private val rawCredentialsDao: RawCredentialsDao) {
val rawCredentials: List<RawCredentials> = rawCredentialsDao.getAllRawCredentials()

@WorkerThread
suspend fun insertRawCredential(credential: RawCredentials) {
rawCredentialsDao.insertRawCredential(credential)
}

@WorkerThread
suspend fun getRawCredentials(): List<RawCredentials> {
return rawCredentialsDao.getAllRawCredentials()
}

@WorkerThread
suspend fun deleteAllRawCredentials(): Int {
return rawCredentialsDao.deleteAllRawCredentials()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ const val VERIFY_DL_PATH = "verify_dl"
const val VERIFY_EA_PATH = "verify_ea"
const val VERIFY_VC_PATH = "verify_vc"
const val VERIFIER_SETTINGS_HOME_PATH = "verifier_settings_home"
const val WALLET_SETTINGS_HOME_PATH = "wallet_settings_home"
const val ADD_TO_WALLET_PATH = "add_to_wallet/{rawCredential}"
const val OID4VP_PATH = "oid4vp/{params}"


sealed class Screen(val route: String) {
Expand All @@ -13,4 +16,7 @@ sealed class Screen(val route: String) {
object VerifyEAScreen : Screen(VERIFY_EA_PATH)
object VerifyVCScreen : Screen(VERIFY_VC_PATH)
object VerifierSettingsHomeScreen : Screen(VERIFIER_SETTINGS_HOME_PATH)
object WalletSettingsHomeScreen : Screen(WALLET_SETTINGS_HOME_PATH)
object AddToWalletScreen : Screen(ADD_TO_WALLET_PATH)
object OID4VPScreen : Screen(OID4VP_PATH)
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
package com.spruceid.mobilesdkexample.navigation

import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.navDeepLink
import com.spruceid.mobilesdkexample.HomeView
import com.spruceid.mobilesdkexample.verifier.VerifyDLView
import com.spruceid.mobilesdkexample.verifier.VerifyEAView
import com.spruceid.mobilesdkexample.verifier.VerifyVCView
import com.spruceid.mobilesdkexample.verifiersettings.VerifierSettingsHomeView
import com.spruceid.mobilesdkexample.viewmodels.IRawCredentialsViewModel
import com.spruceid.mobilesdkexample.wallet.AddToWalletView
import com.spruceid.mobilesdkexample.walletsettings.WalletSettingsHomeView

@Composable
fun SetupNavGraph(
navController: NavHostController
navController: NavHostController,
rawCredentialsViewModel: IRawCredentialsViewModel
) {
NavHost(
navController = navController,
Expand All @@ -21,7 +27,7 @@ fun SetupNavGraph(
composable(
route = Screen.HomeScreen.route,
) {
HomeView(navController)
HomeView(navController, rawCredentialsViewModel)
}
composable(
route = Screen.VerifyDLScreen.route,
Expand All @@ -43,6 +49,32 @@ fun SetupNavGraph(
) {
VerifierSettingsHomeView(navController)
}

composable(
route = Screen.WalletSettingsHomeScreen.route,
) {
WalletSettingsHomeView(navController, rawCredentialsViewModel)
}
composable(
route = Screen.AddToWalletScreen.route,
deepLinks = listOf(
navDeepLink {
uriPattern = "spruceid://?sd-jwt={rawCredential}"
}
)
) { backStackEntry ->
val rawCredential = backStackEntry.arguments?.getString("rawCredential")!!
AddToWalletView(navController, rawCredential, rawCredentialsViewModel)
}
composable(
route = Screen.OID4VPScreen.route,
deepLinks = listOf(
navDeepLink {
uriPattern = "oid4vp://{params}"
}
)
) {
// val params = backStackEntry.arguments?.getString("params")!!
Text(text = "@TODO: OID4VP flow")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ val Primary = Color(0xFFF7F7F5)
val Bg = Color(0xFFFDFDFC)
val CredentialBorder = Color(0xFFE6E1D6)
val CodeBorder = Color(0xff949494)
val CTAButtonGreen = Color(0xFF087455)
val GreenValid = Color(0xFF059669)
val SecondaryButtonRed = Color(0xFFE11D48)
val TextBody = Color(0xFF57534E)
val TextHeader = Color(0xFF0C0A09)
val TextOnPrimary = Color(0xFFA8A29E)
Expand Down
Loading

0 comments on commit fd8bff6

Please sign in to comment.