diff --git a/example/build.gradle.kts b/example/build.gradle.kts index e23c58c..272ca48 100644 --- a/example/build.gradle.kts +++ b/example/build.gradle.kts @@ -12,8 +12,8 @@ android { applicationId = "com.spruceid.mobilesdkexample" minSdk = 26 targetSdk = 34 - versionCode = 13 - versionName = "1.0.0+13" + versionCode = 14 + versionName = "1.1.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { @@ -24,7 +24,10 @@ android { buildTypes { release { isMinifyEnabled = false - proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) } } compileOptions { diff --git a/example/src/main/java/com/spruceid/mobilesdkexample/wallet/HandleOID4VCIView.kt b/example/src/main/java/com/spruceid/mobilesdkexample/wallet/HandleOID4VCIView.kt index f4a1b56..33e5d2b 100644 --- a/example/src/main/java/com/spruceid/mobilesdkexample/wallet/HandleOID4VCIView.kt +++ b/example/src/main/java/com/spruceid/mobilesdkexample/wallet/HandleOID4VCIView.kt @@ -34,9 +34,9 @@ import io.ktor.util.toMap @Composable fun HandleOID4VCIView( - navController: NavHostController, - url: String, - credentialPacksViewModel: CredentialPacksViewModel + navController: NavHostController, + url: String, + credentialPacksViewModel: CredentialPacksViewModel ) { var loading by remember { mutableStateOf(false) } var err by remember { mutableStateOf(null) } @@ -47,38 +47,38 @@ fun HandleOID4VCIView( loading = true val client = HttpClient(CIO) val oid4vciSession = - Oid4vci.newWithAsyncClient( - client = - object : AsyncHttpClient { - override suspend fun httpClient( - request: HttpRequest - ): HttpResponse { - val res = - client.request(request.url) { - method = HttpMethod(request.method) - for ((k, v) in request.headers) { - headers[k] = v - } - setBody(request.body) - } - - return HttpResponse( - statusCode = res.status.value.toUShort(), - headers = - res.headers.toMap().mapValues { - it.value.joinToString() - }, - body = res.readBytes() - ) - } + Oid4vci.newWithAsyncClient( + client = + object : AsyncHttpClient { + override suspend fun httpClient( + request: HttpRequest + ): HttpResponse { + val res = + client.request(request.url) { + method = HttpMethod(request.method) + for ((k, v) in request.headers) { + headers[k] = v } - ) + setBody(request.body) + } + + return HttpResponse( + statusCode = res.status.value.toUShort(), + headers = + res.headers.toMap().mapValues { + it.value.joinToString() + }, + body = res.readBytes() + ) + } + } + ) try { oid4vciSession.initiateWithOffer( - credentialOffer = url, - clientId = "skit-demo-wallet", - redirectUrl = "https://spruceid.com" + credentialOffer = url, + clientId = "skit-demo-wallet", + redirectUrl = "https://spruceid.com" ) val nonce = oid4vciSession.exchangeToken() @@ -90,45 +90,45 @@ fun HandleOID4VCIView( val jwk = keyManager.getJwk(id = "reference-app/default-signing") val signingInput = - jwk?.let { - generatePopPrepare( - audience = metadata.issuer(), - nonce = nonce, - didMethod = DidMethod.JWK, - publicJwk = jwk, - durationInSecs = null - ) - } + jwk?.let { + generatePopPrepare( + audience = metadata.issuer(), + nonce = nonce, + didMethod = DidMethod.JWK, + publicJwk = jwk, + durationInSecs = null + ) + } val signature = - signingInput?.let { - keyManager.signPayload( - id = "reference-app/default-signing", - payload = signingInput - ) - } + signingInput?.let { + keyManager.signPayload( + id = "reference-app/default-signing", + payload = signingInput + ) + } val pop = - signingInput?.let { - signature?.let { - generatePopComplete( - signingInput = signingInput, - signature = - Base64.encodeToString( - signature, - Base64.URL_SAFE or - Base64.NO_PADDING or - Base64.NO_WRAP - ) - .toByteArray() + signingInput?.let { + signature?.let { + generatePopComplete( + signingInput = signingInput, + signature = + Base64.encodeToString( + signature, + Base64.URL_SAFE or + Base64.NO_PADDING or + Base64.NO_WRAP ) - } + .toByteArray() + ) } + } oid4vciSession.setContextMap(getVCPlaygroundOID4VCIContext(ctx = ctx)) val credentials = - pop?.let { oid4vciSession.exchangeCredential(proofsOfPossession = listOf(pop)) } + pop?.let { oid4vciSession.exchangeCredential(proofsOfPossession = listOf(pop)) } credentials?.forEach { cred -> cred.payload.toString(Charsets.UTF_8).let { credential = it } @@ -144,15 +144,15 @@ fun HandleOID4VCIView( LoadingView(loadingText = "Loading...") } else if (err != null) { ErrorView( - errorTitle = "Error Adding Credential", - errorDetails = err!!, - onClose = { navController.navigate(Screen.HomeScreen.route) { popUpTo(0) } } + errorTitle = "Error Adding Credential", + errorDetails = err!!, + onClose = { navController.navigate(Screen.HomeScreen.route) { popUpTo(0) } } ) } else if (credential != null) { AddToWalletView( - navController = navController, - rawCredential = credential!!, - credentialPacksViewModel = credentialPacksViewModel + navController = navController, + rawCredential = credential!!, + credentialPacksViewModel = credentialPacksViewModel ) } } @@ -161,83 +161,90 @@ fun getVCPlaygroundOID4VCIContext(ctx: Context): Map { val context = mutableMapOf() context["https://contexts.vcplayground.org/examples/alumni/v1.json"] = - ctx.resources - .openRawResource(R.raw.contexts_vcplayground_org_examples_alumni_v1) - .bufferedReader() - .readLines() - .joinToString("") + ctx.resources + .openRawResource(R.raw.contexts_vcplayground_org_examples_alumni_v1) + .bufferedReader() + .readLines() + .joinToString("") context["https://w3id.org/first-responder/v1"] = - ctx.resources - .openRawResource(R.raw.w3id_org_first_responder_v1) - .bufferedReader() - .readLines() - .joinToString("") + ctx.resources + .openRawResource(R.raw.w3id_org_first_responder_v1) + .bufferedReader() + .readLines() + .joinToString("") context["https://w3id.org/vdl/aamva/v1"] = - ctx.resources - .openRawResource(R.raw.w3id_org_vdl_aamva_v1) - .bufferedReader() - .readLines() - .joinToString("") + ctx.resources + .openRawResource(R.raw.w3id_org_vdl_aamva_v1) + .bufferedReader() + .readLines() + .joinToString("") context["https://w3id.org/citizenship/v3"] = - ctx.resources - .openRawResource(R.raw.w3id_org_citizenship_v3) - .bufferedReader() - .readLines() - .joinToString("") + ctx.resources + .openRawResource(R.raw.w3id_org_citizenship_v3) + .bufferedReader() + .readLines() + .joinToString("") context["https://contexts.vcplayground.org/examples/movie-ticket/v1.json"] = - ctx.resources - .openRawResource(R.raw.contexts_vcplayground_org_examples_movie_ticket_v1) - .bufferedReader() - .readLines() - .joinToString("") + ctx.resources + .openRawResource(R.raw.contexts_vcplayground_org_examples_movie_ticket_v1) + .bufferedReader() + .readLines() + .joinToString("") context["https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.2.json"] = - ctx.resources - .openRawResource(R.raw.purl_imsglobal_org_spec_ob_v3p0_context_3_0_2) - .bufferedReader() - .readLines() - .joinToString("") + ctx.resources + .openRawResource(R.raw.purl_imsglobal_org_spec_ob_v3p0_context_3_0_2) + .bufferedReader() + .readLines() + .joinToString("") context["https://contexts.vcplayground.org/examples/food-safety-certification/v1.json"] = - ctx.resources - .openRawResource( - R.raw.contexts_vcplayground_org_examples_food_safety_certification_v1 - ) - .bufferedReader() - .readLines() - .joinToString("") + ctx.resources + .openRawResource( + R.raw.contexts_vcplayground_org_examples_food_safety_certification_v1 + ) + .bufferedReader() + .readLines() + .joinToString("") context["https://contexts.vcplayground.org/examples/gs1-8110-coupon/v2.json"] = - ctx.resources - .openRawResource(R.raw.contexts_vcplayground_org_examples_gs1_8110_coupon_v2) - .bufferedReader() - .readLines() - .joinToString("") + ctx.resources + .openRawResource(R.raw.contexts_vcplayground_org_examples_gs1_8110_coupon_v2) + .bufferedReader() + .readLines() + .joinToString("") context["https://contexts.vcplayground.org/examples/customer-loyalty/v1.json"] = - ctx.resources - .openRawResource(R.raw.contexts_vcplayground_org_examples_customer_loyalty_v1) - .bufferedReader() - .readLines() - .joinToString("") + ctx.resources + .openRawResource(R.raw.contexts_vcplayground_org_examples_customer_loyalty_v1) + .bufferedReader() + .readLines() + .joinToString("") context["https://w3id.org/citizenship/v4rc1"] = - ctx.resources - .openRawResource(R.raw.w3id_org_citizenship_v4rc1) - .bufferedReader() - .readLines() - .joinToString("") + ctx.resources + .openRawResource(R.raw.w3id_org_citizenship_v4rc1) + .bufferedReader() + .readLines() + .joinToString("") context["https://w3id.org/vc/render-method/v2rc1"] = - ctx.resources - .openRawResource(R.raw.w3id_org_vc_render_method_v2rc1) - .bufferedReader() - .readLines() - .joinToString("") + ctx.resources + .openRawResource(R.raw.w3id_org_vc_render_method_v2rc1) + .bufferedReader() + .readLines() + .joinToString("") + + context["https://contexts.vcplayground.org/examples/movie-ticket-vcdm-v2/v1.json"] = + ctx.resources + .openRawResource(R.raw.contexts_vcplayground_org_examples_movie_ticket_vcdm_v2_v1) + .bufferedReader() + .readLines() + .joinToString("") return context } diff --git a/example/src/main/res/raw/contexts_vcplayground_org_examples_movie_ticket_vcdm_v2_v1.json b/example/src/main/res/raw/contexts_vcplayground_org_examples_movie_ticket_vcdm_v2_v1.json new file mode 100644 index 0000000..a64fa21 --- /dev/null +++ b/example/src/main/res/raw/contexts_vcplayground_org_examples_movie_ticket_vcdm_v2_v1.json @@ -0,0 +1,38 @@ +{ + "@context": { + "@version": 1.1, + "@protected": true, + "MovieTicketCredential": "https://contexts.vcplayground.org/examples/movie-ticket/vocab#MovieTicketCredential", + "Ticket": "https://schema.org/Ticket", + "owns": { + "@id": "https://schema.org/owns", + "@type": "@id" + }, + "name": "https://schema.org/name", + "description": "https://schema.org/description", + "identifier": "https://schema.org/identifier", + "image": { + "@id": "https://schema.org/image", + "@type": "@id" + }, + "location": { + "@id": "https://schema.org/location", + "@type": "@id" + }, + "startDate": { + "@id": "https://schema.org/startDate", + "@type": "http://www.w3.org/2001/XMLSchema#dateTime" + }, + "ticketNumber": "https://schema.org/ticketNumber", + "ticketedSeat": "https://schema.org/ticketedSeat", + "ticketToken": "https://schema.org/ticketToken", + "seatNumber": "https://schema.org/seatNumber", + "seatRow": "https://schema.org/seatRow", + "seatSection": "https://schema.org/seatSection", + "address": "https://schema.org/address", + "addressLocality": "https://schema.org/addressLocality", + "addressRegion": "https://schema.org/addressRegion", + "postalCode": "https://schema.org/postalCode", + "streetAddress": "https://schema.org/streetAddress" + } +} \ No newline at end of file diff --git a/example/src/main/res/raw/w3id_org_vc_render_method_v2rc1 b/example/src/main/res/raw/w3id_org_vc_render_method_v2rc1.json similarity index 99% rename from example/src/main/res/raw/w3id_org_vc_render_method_v2rc1 rename to example/src/main/res/raw/w3id_org_vc_render_method_v2rc1.json index df725bc..49fa1a9 100644 --- a/example/src/main/res/raw/w3id_org_vc_render_method_v2rc1 +++ b/example/src/main/res/raw/w3id_org_vc_render_method_v2rc1.json @@ -36,4 +36,4 @@ } } } -} +} \ No newline at end of file