Skip to content

Commit

Permalink
[Android][iOS] Holder Activity Logs (#61)
Browse files Browse the repository at this point in the history
This enables activity logs for the holder's actions.
  • Loading branch information
Juliano1612 authored Dec 16, 2024
1 parent c373a66 commit 69eacc7
Show file tree
Hide file tree
Showing 26 changed files with 955 additions and 305 deletions.
4 changes: 2 additions & 2 deletions example/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ android {
applicationId = "com.spruceid.mobilesdkexample"
minSdk = 26
targetSdk = 34
versionCode = 16
versionName = "1.2.0"
versionCode = 20
versionName = "1.3.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import com.spruceid.mobilesdkexample.viewmodels.CredentialPacksViewModel
import com.spruceid.mobilesdkexample.viewmodels.StatusListViewModel
import com.spruceid.mobilesdkexample.viewmodels.HelpersViewModel
import com.spruceid.mobilesdkexample.viewmodels.VerificationMethodsViewModel
import com.spruceid.mobilesdkexample.viewmodels.WalletActivityLogsViewModel
import com.spruceid.mobilesdkexample.wallet.WalletHomeView

enum class HomeTabs {
Expand All @@ -56,6 +57,7 @@ fun HomeView(
initialTab: String,
verificationMethodsViewModel: VerificationMethodsViewModel,
credentialPacksViewModel: CredentialPacksViewModel,
walletActivityLogsViewModel: WalletActivityLogsViewModel,
statusListViewModel: StatusListViewModel,
helpersViewModel: HelpersViewModel
) {
Expand All @@ -81,6 +83,7 @@ fun HomeView(
WalletHomeView(
navController,
credentialPacksViewModel = credentialPacksViewModel,
walletActivityLogsViewModel = walletActivityLogsViewModel,
statusListViewModel = statusListViewModel,
helpersViewModel = helpersViewModel
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import com.spruceid.mobile.sdk.ConnectionLiveData
import com.spruceid.mobilesdkexample.db.AppDatabase
import com.spruceid.mobilesdkexample.db.VerificationActivityLogsRepository
import com.spruceid.mobilesdkexample.db.VerificationMethodsRepository
import com.spruceid.mobilesdkexample.db.WalletActivityLogsRepository
import com.spruceid.mobilesdkexample.navigation.Screen
import com.spruceid.mobilesdkexample.navigation.SetupNavGraph
import com.spruceid.mobilesdkexample.ui.theme.ColorBase1
Expand All @@ -28,6 +29,8 @@ import com.spruceid.mobilesdkexample.viewmodels.VerificationActivityLogsViewMode
import com.spruceid.mobilesdkexample.viewmodels.VerificationActivityLogsViewModelFactory
import com.spruceid.mobilesdkexample.viewmodels.VerificationMethodsViewModel
import com.spruceid.mobilesdkexample.viewmodels.VerificationMethodsViewModelFactory
import com.spruceid.mobilesdkexample.viewmodels.WalletActivityLogsViewModel
import com.spruceid.mobilesdkexample.viewmodels.WalletActivityLogsViewModelFactory

class MainActivity : ComponentActivity() {
private lateinit var navController: NavHostController
Expand Down Expand Up @@ -82,6 +85,10 @@ class MainActivity : ComponentActivity() {
VerificationActivityLogsViewModelFactory((application as MainApplication).verificationActivityLogsRepository)
}

val walletActivityLogsViewModel: WalletActivityLogsViewModel by viewModels {
WalletActivityLogsViewModelFactory((application as MainApplication).walletActivityLogsRepository)
}

val credentialPacksViewModel: CredentialPacksViewModel by viewModels {
CredentialPacksViewModelFactory(application as MainApplication)
}
Expand All @@ -100,6 +107,7 @@ class MainActivity : ComponentActivity() {
navController,
verificationMethodsViewModel = verificationMethodsViewModel,
verificationActivityLogsViewModel = verificationActivityLogsViewModel,
walletActivityLogsViewModel = walletActivityLogsViewModel,
credentialPacksViewModel = credentialPacksViewModel,
statusListViewModel = statusListViewModel,
helpersViewModel = helpersViewModel
Expand All @@ -117,4 +125,5 @@ class MainApplication : Application() {

val verificationMethodsRepository by lazy { VerificationMethodsRepository(db.verificationMethodsDao()) }
val verificationActivityLogsRepository by lazy { VerificationActivityLogsRepository(db.verificationActivityLogsDao()) }
val walletActivityLogsRepository by lazy { WalletActivityLogsRepository(db.walletActivityLogsDao()) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,18 @@ import androidx.navigation.NavHostController
import com.spruceid.mobile.sdk.CredentialPack
import com.spruceid.mobilesdkexample.ErrorView
import com.spruceid.mobilesdkexample.LoadingView
import com.spruceid.mobilesdkexample.db.WalletActivityLogs
import com.spruceid.mobilesdkexample.navigation.Screen
import com.spruceid.mobilesdkexample.ui.theme.ColorEmerald700
import com.spruceid.mobilesdkexample.ui.theme.ColorRose600
import com.spruceid.mobilesdkexample.ui.theme.ColorStone950
import com.spruceid.mobilesdkexample.ui.theme.Inter
import com.spruceid.mobilesdkexample.utils.credentialDisplaySelector
import com.spruceid.mobilesdkexample.utils.getCredentialIdTitleAndIssuer
import com.spruceid.mobilesdkexample.utils.getCurrentSqlDate
import com.spruceid.mobilesdkexample.viewmodels.CredentialPacksViewModel
import com.spruceid.mobilesdkexample.viewmodels.StatusListViewModel
import com.spruceid.mobilesdkexample.viewmodels.WalletActivityLogsViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
Expand All @@ -43,6 +47,7 @@ fun AddToWalletView(
navController: NavHostController,
rawCredential: String,
credentialPacksViewModel: CredentialPacksViewModel,
walletActivityLogsViewModel: WalletActivityLogsViewModel,
statusListViewModel: StatusListViewModel
) {
var credentialItem by remember { mutableStateOf<ICredentialView?>(null) }
Expand Down Expand Up @@ -70,6 +75,18 @@ fun AddToWalletView(
val credentialPack = CredentialPack()
credentialPack.tryAddRawCredential(rawCredential)
credentialPacksViewModel.saveCredentialPack(credentialPack)
val credentialInfo = getCredentialIdTitleAndIssuer(credentialPack)
walletActivityLogsViewModel.saveWalletActivityLog(
walletActivityLogs = WalletActivityLogs(
credentialPackId = credentialPack.id().toString(),
credentialId = credentialInfo.first,
credentialTitle = credentialInfo.second,
issuer = credentialInfo.third,
action = "Claimed",
dateTime = getCurrentSqlDate(),
additionalInformation = ""
)
)
} catch (e: Exception) {
error = e.localizedMessage
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@ import androidx.sqlite.db.SupportSQLiteDatabase

@Database(
entities = [
WalletActivityLogs::class,
VerificationActivityLogs::class,
RawCredentials::class,
VerificationMethods::class
],
version = 4
version = 5
)
@TypeConverters(*[DateConverter::class])
abstract class AppDatabase : RoomDatabase() {
abstract fun walletActivityLogsDao(): WalletActivityLogsDao
abstract fun verificationActivityLogsDao(): VerificationActivityLogsDao
abstract fun rawCredentialsDao(): RawCredentialsDao
abstract fun verificationMethodsDao(): VerificationMethodsDao
Expand All @@ -36,6 +38,7 @@ abstract class AppDatabase : RoomDatabase() {
)
.addMigrations(MIGRATION_2_3)
.addMigrations(MIGRATION_3_4)
.addMigrations(MIGRATION_4_5)
.allowMainThreadQueries()
.build()
dbInstance = instance
Expand Down Expand Up @@ -74,3 +77,20 @@ val MIGRATION_3_4 = object : Migration(3, 4) {
)
}
}

val MIGRATION_4_5 = object : Migration(4, 5) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL(
"CREATE TABLE `wallet_activity_logs` (" +
"`id` INTEGER NOT NULL, " +
"`credentialPackId` TEXT NOT NULL, " +
"`credentialId` TEXT NOT NULL, " +
"`credentialTitle` TEXT NOT NULL, " +
"`issuer` TEXT NOT NULL, " +
"`action` TEXT NOT NULL, " +
"`dateTime` INTEGER NOT NULL, " +
"`additionalInformation` TEXT NOT NULL, " +
"PRIMARY KEY(`id`))"
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query

@Dao
interface WalletActivityLogsDao {
@Insert
suspend fun insertWalletActivity(walletActivityLogs: WalletActivityLogs)

@Query("SELECT * FROM wallet_activity_logs ORDER BY dateTime DESC")
fun getAllWalletActivityLogs(): List<WalletActivityLogs>
}

@Dao
interface VerificationActivityLogsDao {
@Insert
Expand Down
12 changes: 12 additions & 0 deletions example/src/main/java/com/spruceid/mobilesdkexample/db/Entities.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@ import androidx.room.Entity
import androidx.room.PrimaryKey
import java.sql.Date

@Entity(tableName = "wallet_activity_logs")
data class WalletActivityLogs(
@PrimaryKey(autoGenerate = true) val id: Long = 0,
val credentialPackId: String,
val credentialId: String,
val credentialTitle: String,
val issuer: String,
val action: String,
val dateTime: Date,
val additionalInformation: String,
)

@Entity(tableName = "verification_activity_logs")
data class VerificationActivityLogs(
@PrimaryKey(autoGenerate = true) val id: Long = 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,21 @@ package com.spruceid.mobilesdkexample.db
import androidx.annotation.WorkerThread
import java.sql.Date

class WalletActivityLogsRepository(private val walletActivityLogsDao: WalletActivityLogsDao) {
val walletActivityLogs: List<WalletActivityLogs> =
walletActivityLogsDao.getAllWalletActivityLogs()

@WorkerThread
suspend fun insertWalletActivityLog(walletActivityLogs: WalletActivityLogs) {
walletActivityLogsDao.insertWalletActivity(walletActivityLogs)
}

@WorkerThread
suspend fun getWalletActivityLogs(): List<WalletActivityLogs> {
return walletActivityLogsDao.getAllWalletActivityLogs()
}
}

class VerificationActivityLogsRepository(private val verificationActivityLogsDao: VerificationActivityLogsDao) {
val verificationActivityLogs: List<VerificationActivityLogs> =
verificationActivityLogsDao.getAllVerificationActivityLogs()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const val VERIFIER_SETTINGS_HOME_PATH = "verifier_settings_home"
const val VERIFIER_SETTINGS_ACTIVITY_LOG = "verifier_settings_activity_log"
const val ADD_VERIFICATION_METHOD_PATH = "add_verification_method"
const val WALLET_SETTINGS_HOME_PATH = "wallet_settings_home"
const val WALLET_SETTINGS_ACTIVITY_LOG = "wallet_settings_activity_log"
const val ADD_TO_WALLET_PATH = "add_to_wallet/{rawCredential}"
const val SCAN_QR_PATH = "scan_qr"
const val HANDLE_OID4VCI_PATH = "oid4vci/{url}"
Expand All @@ -26,6 +27,7 @@ sealed class Screen(val route: String) {
object VerifierSettingsActivityLogScreen : Screen(VERIFIER_SETTINGS_ACTIVITY_LOG)
object AddVerificationMethodScreen : Screen(ADD_VERIFICATION_METHOD_PATH)
object WalletSettingsHomeScreen : Screen(WALLET_SETTINGS_HOME_PATH)
object WalletSettingsActivityLogScreen : Screen(WALLET_SETTINGS_ACTIVITY_LOG)
object AddToWalletScreen : Screen(ADD_TO_WALLET_PATH)
object ScanQRScreen : Screen(SCAN_QR_PATH)
object HandleOID4VCI : Screen(HANDLE_OID4VCI_PATH)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,19 @@ import com.spruceid.mobilesdkexample.viewmodels.HelpersViewModel
import com.spruceid.mobilesdkexample.viewmodels.StatusListViewModel
import com.spruceid.mobilesdkexample.viewmodels.VerificationActivityLogsViewModel
import com.spruceid.mobilesdkexample.viewmodels.VerificationMethodsViewModel
import com.spruceid.mobilesdkexample.viewmodels.WalletActivityLogsViewModel
import com.spruceid.mobilesdkexample.wallet.DispatchQRView
import com.spruceid.mobilesdkexample.wallet.HandleOID4VCIView
import com.spruceid.mobilesdkexample.wallet.HandleOID4VPView
import com.spruceid.mobilesdkexample.walletsettings.WalletSettingsActivityLogScreen
import com.spruceid.mobilesdkexample.walletsettings.WalletSettingsHomeView

@Composable
fun SetupNavGraph(
navController: NavHostController,
verificationMethodsViewModel: VerificationMethodsViewModel,
verificationActivityLogsViewModel: VerificationActivityLogsViewModel,
walletActivityLogsViewModel: WalletActivityLogsViewModel,
credentialPacksViewModel: CredentialPacksViewModel,
statusListViewModel: StatusListViewModel,
helpersViewModel: HelpersViewModel
Expand All @@ -51,6 +54,7 @@ fun SetupNavGraph(
initialTab = tab,
verificationMethodsViewModel = verificationMethodsViewModel,
credentialPacksViewModel = credentialPacksViewModel,
walletActivityLogsViewModel = walletActivityLogsViewModel,
statusListViewModel = statusListViewModel,
helpersViewModel = helpersViewModel
)
Expand Down Expand Up @@ -123,7 +127,22 @@ fun SetupNavGraph(
}
composable(
route = Screen.WalletSettingsHomeScreen.route,
) { WalletSettingsHomeView(navController, credentialPacksViewModel) }
) {
WalletSettingsHomeView(
navController,
credentialPacksViewModel,
walletActivityLogsViewModel
)
}
composable(
route = Screen.WalletSettingsActivityLogScreen.route,
) {
WalletSettingsActivityLogScreen(
navController,
walletActivityLogsViewModel = walletActivityLogsViewModel,
helpersViewModel = helpersViewModel
)
}
composable(
route = Screen.AddToWalletScreen.route,
deepLinks =
Expand All @@ -134,6 +153,7 @@ fun SetupNavGraph(
navController,
rawCredential,
credentialPacksViewModel,
walletActivityLogsViewModel,
statusListViewModel
)
}
Expand All @@ -144,7 +164,13 @@ fun SetupNavGraph(
route = Screen.HandleOID4VCI.route,
) { backStackEntry ->
val url = backStackEntry.arguments?.getString("url")!!
HandleOID4VCIView(navController, url, credentialPacksViewModel, statusListViewModel)
HandleOID4VCIView(
navController,
url,
credentialPacksViewModel,
walletActivityLogsViewModel,
statusListViewModel
)
}
composable(
route = Screen.HandleOID4VP.route,
Expand All @@ -154,7 +180,12 @@ fun SetupNavGraph(
if (!url.startsWith("openid4vp")) {
url = "openid4vp://$url"
}
HandleOID4VPView(navController, url, credentialPacksViewModel)
HandleOID4VPView(
navController,
url,
credentialPacksViewModel,
walletActivityLogsViewModel
)
}
}
}
Loading

0 comments on commit 69eacc7

Please sign in to comment.