Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .github/workflows/ktlint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: ktlint

on:
push:
branches:
- main
paths:
- MultipazCodelab/Holder/**
pull_request:
branches:
- main
paths:
- MultipazCodelab/Holder/**

jobs:
ktlint:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up JDK
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17
cache: gradle

- name: Run ktlint check
id: ktlint
run: |
cd MultipazCodelab/Holder/
chmod +x gradlew
./gradlew ktlintCheck
1 change: 1 addition & 0 deletions ComposeWallet/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ plugins {
alias(libs.plugins.composeMultiplatform) apply false
alias(libs.plugins.composeCompiler) apply false
alias(libs.plugins.kotlinMultiplatform) apply false
alias(libs.plugins.kotlinSerialization) apply false
}
12 changes: 9 additions & 3 deletions ComposeWallet/composeApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@ plugins {
alias(libs.plugins.androidApplication)
alias(libs.plugins.composeMultiplatform)
alias(libs.plugins.composeCompiler)
alias(libs.plugins.kotlinSerialization)
}

kotlin {
jvmToolchain(17)

androidTarget {
@OptIn(ExperimentalKotlinGradlePluginApi::class)
compilerOptions {
jvmTarget.set(JvmTarget.JVM_11)
jvmTarget.set(JvmTarget.JVM_17)
}
}

Expand Down Expand Up @@ -64,6 +67,9 @@ kotlin {
implementation(libs.multipaz.dcapi)
implementation(libs.multipaz.compose)
implementation(libs.coil.compose)
implementation(libs.coil.ktor3)
implementation(libs.navigation.compose)
implementation(libs.kotlinx.serialization.json)
}
commonTest.dependencies {
implementation(libs.kotlin.test)
Expand Down Expand Up @@ -93,8 +99,8 @@ android {
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
}

Expand Down
27 changes: 16 additions & 11 deletions ComposeWallet/composeApp/src/androidMain/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
<data
android:scheme="https"
android:host="apps.multipaz.org"
android:pathPattern="/redirect/org.multipaz.samples.wallet.cmp"/>
android:pathPattern="/redirect/org.multipaz.samples.wallet.cmp/"/>
</intent-filter>

<!-- 2. OpenID4VCI Credential Offers -->
Expand All @@ -82,7 +82,7 @@
</activity>

<activity
android:name=".CredmanActivity"
android:name=".CredentialManagerPresentmentActivity"
android:exported="true"
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden|mnc|colorMode|density|fontScale|fontWeightAdjustment|keyboard|layoutDirection|locale|mcc|navigation|smallestScreenSize|touchscreen|uiMode"
android:theme="@android:style/Theme.Translucent"
Expand All @@ -94,18 +94,23 @@
</intent-filter>
</activity>

<!-- NOTE: This app uses made-up credentials so it's not a concern to handle credential
requests on the lock screen because there is no PII. For an app with real
user data it might be a privacy problem to show PII on the lock screen.
-->
<activity
android:name=".NfcActivity"
android:showWhenLocked="true"
android:turnScreenOn="true"
android:name=".UriSchemePresentmentActivity"
android:exported="true"
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden|mnc|colorMode|density|fontScale|fontWeightAdjustment|keyboard|layoutDirection|locale|mcc|navigation|smallestScreenSize|touchscreen|uiMode"
android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen"
android:launchMode="singleInstance">
android:theme="@android:style/Theme.Translucent"
android:launchMode="singleInstance"
android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Various OpenID4VP schemes -->
<data android:scheme="haip-vp"/>
<data android:scheme="openid4vp"/>
<!-- Accept all hosts for any of the defined schemes above -->
<data android:host="*"/>
</intent-filter>
</activity>

<service
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.multipaz.samples.wallet.cmp

import io.ktor.client.engine.HttpClientEngineFactory
import io.ktor.client.engine.android.Android
import org.multipaz.context.applicationContext
import org.multipaz.storage.Storage
import org.multipaz.util.Platform

@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING")
actual object AppPlatform {

actual val storage: Storage = Platform.nonBackedUpStorage

actual val redirectPath: String = "/redirect/${applicationContext.packageName}/"

actual val httpClientEngineFactory: HttpClientEngineFactory<*> by lazy {
Android
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.multipaz.samples.wallet.cmp

import mpzcmpwallet.composeapp.generated.resources.Res
import org.multipaz.compose.digitalcredentials.CredentialManagerPresentmentActivity

class CredentialManagerPresentmentActivity: CredentialManagerPresentmentActivity() {
override suspend fun getSettings(): Settings {
val app = App.getInstance()
app.init()
return Settings(
source = app.presentmentSource,
privilegedAllowList = Res.readBytes("files/privilegedUserAgents.json").decodeToString()
)
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class MainActivity : FragmentActivity() {
initializeApplication(this.applicationContext)
enableEdgeToEdge()
super.onCreate(savedInstanceState)
handleIntent(intent)

lifecycle.coroutineScope.launch {
val app = App.getInstance()
app.init()
Expand All @@ -59,7 +59,7 @@ class MainActivity : FragmentActivity() {
AppLinksCheck.checkAppLinksServerSetup(
context = this@MainActivity,
appLinkServer = ProvisioningSupport.APP_LINK_SERVER,
httpClient = HttpClient(platformHttpClientEngineFactory())
httpClient = HttpClient(AppPlatform.httpClientEngineFactory)
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,31 @@
package org.multipaz.samples.wallet.cmp

import org.multipaz.compose.mdoc.MdocNdefService
import org.multipaz.compose.prompt.PresentmentActivity
import org.multipaz.crypto.EcCurve
import org.multipaz.mdoc.transport.MdocTransportOptions

class NdefService: MdocNdefService() {

override suspend fun getSettings(): Settings {
// TODO: optimize initialization of App so we can just get settingsModel and presentmentSource() out
val app = App.getInstance()
app.init()

val source = app.presentmentSource
PresentmentActivity.presentmentModel.reset(
documentStore = source.documentStore,
documentTypeRepository = source.documentTypeRepository,
// TODO: if user is currently selecting a document, pass it here
preselectedDocuments = emptyList()
)

return Settings(
source = source,
promptModel = PresentmentActivity.promptModel,
presentmentModel = PresentmentActivity.presentmentModel,
activityClass = PresentmentActivity::class.java,
sessionEncryptionCurve = EcCurve.P256,
allowMultipleRequests = false,
useNegotiatedHandover = true,
negotiatedHandoverPreferredOrder = listOf(
"ble:central_client_mode:",
Expand All @@ -18,9 +34,7 @@ class NdefService: MdocNdefService() {
staticHandoverBleCentralClientModeEnabled = false,
staticHandoverBlePeripheralServerModeEnabled = false,
staticHandoverNfcDataTransferEnabled = false,
transportOptions = MdocTransportOptions(bleUseL2CAP = true),
promptModel = App.promptModel,
presentmentActivityClass = NfcActivity::class.java,
transportOptions = MdocTransportOptions(bleUseL2CAPInEngagement = true),
)
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.multipaz.samples.wallet.cmp

import org.multipaz.compose.presentment.UriSchemePresentmentActivity

class UriSchemePresentmentActivity: UriSchemePresentmentActivity() {
override suspend fun getSettings(): Settings {
val app = App.getInstance()
app.init()
return Settings(
source = app.presentmentSource,
httpClientEngineFactory = AppPlatform.httpClientEngineFactory,
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="#FFFFFF">
<group android:scaleX="0.92"
android:scaleY="0.92"
android:translateX="0.96"
android:translateY="0.96">
<path
android:fillColor="@android:color/white"
android:pathData="M18,4H6C3.79,4 2,5.79 2,8v8c0,2.21 1.79,4 4,4h12c2.21,0 4,-1.79 4,-4V8C22,5.79 20.21,4 18,4zM16.14,13.77c-0.24,0.2 -0.57,0.28 -0.88,0.2L4.15,11.25C4.45,10.52 5.16,10 6,10h12c0.67,0 1.26,0.34 1.63,0.84L16.14,13.77zM6,6h12c1.1,0 2,0.9 2,2v0.55C19.41,8.21 18.73,8 18,8H6C5.27,8 4.59,8.21 4,8.55V8C4,6.9 4.9,6 6,6z"/>
</group>
</vector>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<group android:scaleX="0.65"
android:scaleY="0.65"
android:translateX="18.9"
android:translateY="18.9">
</group>
</vector>
Loading