### Run Verifier Service Locally Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/README.md Execute this command to start the service on your local machine. Ensure you have Gradle installed and the project is set up correctly. ```bash ./gradlew bootRun ``` -------------------------------- ### Configuration Scenarios Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/_autodocs/MANIFEST.md Showcases different configuration scenarios for the verifier endpoint. These examples cover various setup options and best practices. ```yaml # Configuration examples (4 scenarios) ``` -------------------------------- ### Start Docker Compose Environment Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/README.md Use this command to start all verifier services, including the verifier backend, UI, and haproxy, in detached mode. ```bash # From project root directory cd docker docker-compose up -d ``` -------------------------------- ### Kotlin Backend Integration Example Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/_autodocs/MANIFEST.md Illustrates how to integrate with the verifier endpoint using Kotlin. This example covers common backend operations and interactions. ```kotlin // Kotlin backend integration examples (20+ examples) ``` -------------------------------- ### Minimal Development Setup Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/_autodocs/configuration.md A minimal configuration for development, enabling specific VP formats and setting the response mode. ```properties verifier.publicUrl=http://localhost:8080 verifier.clientMetadata.vpFormats.sdJwtVc.enabled=true verifier.clientMetadata.vpFormats.msoMdoc.enabled=true verifier.response.mode=DirectPost ``` -------------------------------- ### InitTransaction Usage Examples Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/_autodocs/api-reference/01-init-transaction.md Demonstrates how to use the InitTransaction function with various configurations. ```APIDOC ## InitTransaction ### Description Initializes a new transaction for requesting credentials. This involves validating the request, generating transaction and request IDs, creating a signed JAR (JWT Secured Authorization Request), and storing the presentation state. ### Method `initTransaction(request: InitTransactionTO)` ### Parameters #### Request Body (`InitTransactionTO`) - **nonce** (string) - Required - A unique string to prevent replay attacks. - **presentationDefinition** (JsonObject) - Required - Defines the credentials to be requested. - **output** (Output) - Required - Specifies the desired output format (e.g., `Output.Json`, `Output.QrCode`). - **transactionData** (List?) - Optional - Additional data for specific transaction types, like qualified electronic signatures. ### Response #### Success Response - **InitTransactionResponse.JwtSecuredAuthorizationRequestTO**: Returned when `output` is `Output.Json`. Contains: - **transactionId** (string) - The unique identifier for the transaction. - **clientId** (string) - The client identifier. - **requestUri** (string) - The URI for the authorization request. - **requestUriMethod** (string) - The HTTP method to use for the request URI. - **InitTransactionResponse.QrCode**: Returned when `output` is `Output.QrCode`. Contains: - **transactionId** (string) - The unique identifier for the transaction. - **qrCode** (ByteArray) - The QR code image data (PNG format). ### Request Example: Minimal DCQL Request (JSON Response) ```kotlin val initTransaction: InitTransaction = // injected val request = InitTransactionTO( nonce = "abc123", presentationDefinition = buildJsonObject { put("id", "pid-request") putJsonArray("credentials") { add(buildJsonObject { put("id", "pid") put("format", "mso_mdoc") put("doctype", "eu.europa.ec.eudi.pid.1") }) } }, output = Output.Json, ) val result = initTransaction(request) when (result) { is InitTransactionResponse.JwtSecuredAuthorizationRequestTO -> { println("Transaction: ${result.transactionId}") println("Client ID: ${result.clientId}") println("Request URI: ${result.requestUri}") println("URI Method: ${result.requestUriMethod}") } is InitTransactionResponse.QrCode -> { // Handle QR code image } } ``` ### Request Example: QR Code Request (for Same-Device Flow) ```kotlin val request = InitTransactionTO( nonce = "xyz789", presentationDefinition = buildJsonObject { put("id", "mdl-request") putJsonArray("credentials") { add(buildJsonObject { put("id", "mDL") put("format", "mso_mdoc") put("doctype", "org.iso.18013.5.1.mDL") }) } }, output = Output.QrCode, // Request QR code instead of JSON ) when (val result = initTransaction(request)) { is InitTransactionResponse.QrCode -> { // result.qrCode is ByteArray containing PNG // Send to frontend for display return ResponseEntity.ok() .contentType(MediaType.IMAGE_PNG) .header("Transaction-Id", result.transactionId) .body(result.qrCode) } else -> {} } ``` ### Request Example: Transaction Data (RQES Signing Request) ```kotlin val transactionData = TransactionData( type = "qualified_electronic_signature_request", credentialIds = nonEmptyListOf("eIDAS_QES"), ).fold( { error -> throw error }, { it }, ) val request = InitTransactionTO( nonce = "qes-123", presentationDefinition = buildJsonObject { put("id", "qes-request") putJsonArray("credentials") { add(buildJsonObject { put("id", "eIDAS_QES") put("format", "mso_mdoc") put("doctype", "eu.europa.ec.eudi.qeaa.1") }) } }, transactionData = listOf(transactionData.base64Url), output = Output.Json, ) when (val result = initTransaction(request)) { is InitTransactionResponse.JwtSecuredAuthorizationRequestTO -> { // Wallet will include transaction_data in response println("Transaction ID: ${result.transactionId}") } else -> {} } ``` ``` -------------------------------- ### Branch naming convention examples Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/CONTRIBUTING.md Examples of valid branch names following the specified convention. ```text feat/add-new-button fix/typo-in-readme docs/update-contributing-guide style/format-code refactor/extract-method test/add-unit-tests chore/update-dependencies ``` -------------------------------- ### JavaScript/TypeScript Frontend Example Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/_autodocs/MANIFEST.md Demonstrates frontend integration with the verifier endpoint using JavaScript or TypeScript. This example shows how to interact with the API from a client-side application. ```javascript // JavaScript/TypeScript frontend examples (2 examples) ``` -------------------------------- ### With Presentation Definition URI Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/_autodocs/api-reference/01-init-transaction.md This example shows how to initialize a transaction by providing a URI for the presentation definition. It also demonstrates the option to resolve the presentation definition on the server. ```APIDOC ## Initialize Transaction with Presentation Definition URI ### Description Initializes a transaction using a remote presentation definition URI and optionally resolves it on the server. ### Method `initTransaction` ### Parameters - `request` (InitTransactionTO) - Required - The transaction initialization object. - `nonce` (string) - Required - A unique nonce for the transaction. - `presentationDefinitionUri` (string) - Required - The URI of the presentation definition. - `presentationDefinitionResolveOnServer` (boolean) - Optional - Whether to resolve the definition on the server. - `output` (Output) - Required - The output format (e.g., `Output.Json`). ### Request Example ```kotlin val request = InitTransactionTO( nonce = "remote-def-123", presentationDefinitionUri = "https://issuer.example.com/definitions/pid-request", presentationDefinitionResolveOnServer = true, // Resolve on server output = Output.Json, ) ``` ### Response #### Success Response - `InitTransactionResponse.JwtSecuredAuthorizationRequestTO` - Contains the authorization request URI. ### Response Example ```kotlin when (val result = initTransaction(request)) { is InitTransactionResponse.JwtSecuredAuthorizationRequestTO -> { println("Definition resolved and transaction created") println("Authorization URI: ${result.authorizationRequestUri}") } else -> {} } ``` ``` -------------------------------- ### Spring WebFlux Reactive Example Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/_autodocs/MANIFEST.md Provides examples of using Spring WebFlux for reactive programming with the verifier endpoint. This is suitable for building non-blocking, high-performance applications. ```java // Spring WebFlux reactive examples (5+ examples) ``` -------------------------------- ### HAIP (High Assurance Issuance Presentation) Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/_autodocs/api-reference/01-init-transaction.md This example demonstrates how to initialize a transaction for a High Assurance Issuance Presentation (HAIP) using the `InitTransactionTO` object. It includes providing the verifier's certificate and specifying supported VP formats. ```APIDOC ## Initialize Transaction for HAIP ### Description Initializes a transaction for a High Assurance Issuance Presentation (HAIP). ### Method `initTransaction` ### Parameters - `request` (InitTransactionTO) - Required - The transaction initialization object. - `nonce` (string) - Required - A unique nonce for the transaction. - `presentationDefinition` (JsonObject) - Required - The presentation definition. - `accessCertificate` (string) - Required - The verifier's certificate for signature. - `walletMetadata` (JsonObject) - Required - Metadata about the wallet. - `profile` (ProfileTO) - Required - The profile for the transaction (e.g., `ProfileTO.OpenId4Vp`). - `responseUriMethod` (ResponseModeTO) - Required - The response mode (e.g., `ResponseModeTO.DirectPostJwt`). - `output` (Output) - Required - The output format (e.g., `Output.Json`). ### Request Example ```kotlin val request = InitTransactionTO( nonce = "haip-001", presentationDefinition = buildJsonObject { put("id", "haip-request") putJsonArray("credentials") { add(buildJsonObject { put("id", "pid") put("format", "sd+jwt-vc") put("vct", "urn:eudi:pid:1") }) } }, accessCertificate = "-----BEGIN CERTIFICATE-----\nMIICljCCAX4CCQDDi/LnzCvWJDANBgkqhkiG9w0BAQsFADANMQswCQYDVQQGEwJ...\n-----END CERTIFICATE-----", walletMetadata = buildJsonObject { put("vp_formats_supported", buildJsonObject { put("sd_jwt_vc", buildJsonObject { putJsonArray("alg") { add("ES256") } putJsonArray("kb_jwt_alg") { add("ES256") } }) put("mso_mdoc", buildJsonObject { putJsonArray("alg") { add(-7) } // ECDSA_256 putJsonArray("device_alg") { add(-7) } }) }) }, profile = ProfileTO.OpenId4Vp, responseUriMethod = ResponseModeTO.DirectPostJwt, // HAIP requires JWT output = Output.Json, ) ``` ### Response #### Success Response - `InitTransactionResponse.JwtSecuredAuthorizationRequestTO` - Contains the client ID in x509_hash format. ### Response Example ```kotlin when (val result = initTransaction(request)) { is InitTransactionResponse.JwtSecuredAuthorizationRequestTO -> { assert(result.clientId.startsWith("x509_hash:")) println("HAIP Client ID: ${result.clientId}") } else -> {} } ``` ``` -------------------------------- ### POST Request with Wallet Metadata Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/_autodocs/api-reference/02-retrieve-request-object.md This example demonstrates a POST request to retrieve a request object, including wallet metadata and nonce. It shows how to handle errors related to unparsable, unsupported, or invalid wallet metadata. ```kotlin val requestId = RequestId("req-xyz789") val walletMetadata = """ { "vp_formats_supported": { "sd_jwt_vc": { "alg": ["ES256", "ES512"], "kb_jwt_alg": ["ES256"] }, "mso_mdoc": { "alg": [-7, -35, -36], "device_alg": [-7, -35] } } """.trimIndent() val walletNonce = "wallet-nonce-xyz" val method = RetrieveRequestObjectMethod.Post( walletMetadata = walletMetadata, walletNonce = walletNonce, ) try { val jwt = retrieveRequestObject(requestId, method) return ResponseEntity.ok() .contentType(MediaType("application", "oauth-authz-req+jwt")) .body(jwt) } catch (error: RetrieveRequestObjectError) { val errorResponse = when (error) { is RetrieveRequestObjectError.UnparsableWalletMetadata -> { mapOf("error" to "invalid_request", "description" to error.message) } is RetrieveRequestObjectError.UnsupportedWalletMetadata -> { mapOf("error" to "invalid_request", "description" to error.message) } is RetrieveRequestObjectError.InvalidWalletMetadata -> { mapOf("error" to "invalid_request", "description" to error.message) } else -> { mapOf("error" to "server_error") } } return ResponseEntity.badRequest().body(errorResponse) } ``` -------------------------------- ### Wallet Metadata Validation Example Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/_autodocs/api-reference/02-retrieve-request-object.md Illustrates how wallet metadata, specifically supported VP formats and algorithms, is validated against verifier configurations. It shows scenarios where metadata is accepted or potentially rejected based on supported algorithms. ```kotlin // Example: Wallet declares support for SD-JWT VC with ES256 val walletMetadata = Json.decodeFromString(""" { "vp_formats_supported": { "sd_jwt_vc": { "alg": ["ES256"], "kb_jwt_alg": ["ES256"] } } } """) // Verifier config: supports SD-JWT VC with ES256, ES384, ES512 // Result: Metadata accepted (ES256 is supported) // If wallet only declared ES512 but verifier config only allows ES256: val walletMetadataNarrow = Json.decodeFromString(""" { "vp_formats_supported": { "sd_jwt_vc": { "alg": ["ES512"], "kb_jwt_alg": ["ES512"] } } } """) // Result: May be accepted or rejected depending on validation rules ``` -------------------------------- ### QR Code Request (Same-Device Flow) Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/_autodocs/api-reference/01-init-transaction.md This example demonstrates how to request a QR code for a same-device flow. Set `output` to `Output.QrCode` and handle the `ByteArray` response containing the PNG image. ```kotlin val request = InitTransactionTO( nonce = "xyz789", presentationDefinition = buildJsonObject { put("id", "mdl-request") putJsonArray("credentials") { add(buildJsonObject { put("id", "mDL") put("format", "mso_mdoc") put("doctype", "org.iso.18013.5.1.mDL") }) } }, output = Output.QrCode, // Request QR code instead of JSON ) when (val result = initTransaction(request)) { is InitTransactionResponse.QrCode -> { // result.qrCode is ByteArray containing PNG // Send to frontend for display return ResponseEntity.ok() .contentType(MediaType.IMAGE_PNG) .header("Transaction-Id", result.transactionId) .body(result.qrCode) } else -> {} } ``` -------------------------------- ### Mount External Keystore for Signing Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/README.md Example Docker Compose configuration demonstrating how to mount an external keystore. This is used for Authorization Request signing. Specify the keystore type, passwords, alias, and the host path to the keystore file. ```yaml verifier: image: ghcr.io/eu-digital-identity-wallet/eudi-srv-verifier-endpoint:latest container_name: verifier-backend ports: - "8080:8080" environment: VERIFIER_PUBLICURL: "https://10.240.174.10" VERIFIER_RESPONSE_MODE: "DirectPost" VERIFIER_ACCESS_CERTIFICATE_KEYSTORE: file:///certs/keystore.jks VERIFIER_ACCESS_CERTIFICATE_KEYSTORE_TYPE: "jks" VERIFIER_ACCESS_CERTIFICATE_KEYSTORE_PASSWORD: VERIFIER_ACCESS_CERTIFICATE_ALIAS: VERIFIER_ACCESS_CERTIFICATE_PASSWORD: volumes: - /keystore.jks:/certs/keystore.jks ``` -------------------------------- ### Configure HTTP Proxy URL Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/README.md Set the VERIFIER_HTTP_PROXY_URL environment variable to specify an optional HTTP proxy server. Example: http://exmaple.com. ```bash export VERIFIER_HTTP_PROXY_URL="http://exmaple.com" ``` -------------------------------- ### Verifier Endpoint Response (Same Device) Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/README.md Example HTTP response for a successful same-device wallet response, indicating a redirect URI for further processing. ```http HTTP/1.1 200 OK { "redirect_uri" : "https://dev.verifier.eudiw.dev/get-wallet-code?response_code=5272d373-ebab-40ec-b44d-0a9909d0da69" } ``` -------------------------------- ### Initialize Transaction Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/README.md Initiates a presentation transaction by sending a request with DCQL query, nonce, and issuer chain. This endpoint is used to start the process of verifying a user's identity. ```APIDOC ## POST /ui/presentations ### Description Initiates a presentation transaction. This endpoint allows the verifier to request credentials from the user's wallet based on a defined DCQL query and other parameters. ### Method POST ### Endpoint /ui/presentations ### Parameters #### Request Body - **dcql_query** (object) - Required - The Data Credential Query Language query specifying the credentials and claims to be requested. - **credentials** (array) - Required - A list of credential objects to be requested. - **id** (string) - Required - Unique identifier for the credential. - **format** (string) - Required - The format of the credential (e.g., "mso_mdoc"). - **meta** (object) - Required - Metadata about the credential. - **doctype_value** (string) - Required - The specific document type value (e.g., "eu.europa.ec.eudi.pid.1"). - **claims** (array) - Required - A list of claims to be extracted from the credential. - **path** (array) - Required - The path to the claim within the credential structure. - **credential_sets** (array) - Required - Defines options and purpose for credential sets. - **options** (array) - Required - Options for selecting credentials. - **purpose** (string) - Required - The purpose for requesting the credentials. - **nonce** (string) - Required - A unique nonce for the transaction. - **jar_mode** (string) - Required - The JAR mode for the transaction (e.g., "by_reference"). - **request_uri_method** (string) - Required - The HTTP method to be used for the request URI (e.g., "post"). - **issuer_chain** (string) - Required - The certificate chain of the issuer. - **profile** (string) - Required - The profile for the transaction (e.g., "openid4vp"). ### Request Example ```json { "dcql_query": { "credentials": [ { "id": "32f54163-7166-48f1-93d8-ff217bdb0653", "format": "mso_mdoc", "meta": { "doctype_value": "eu.europa.ec.eudi.pid.1" }, "claims": [ { "path": ["eu.europa.ec.eudi.pid.1", "family_name"] } ] } ], "credential_sets": [ { "options": [ [ "32f54163-7166-48f1-93d8-ff217bdb0653" ] ], "purpose": "We need to verify your identity" } ] }, "nonce": "nonce", "jar_mode": "by_reference", "request_uri_method": "post", "issuer_chain": "-----BEGIN CERTIFICATE-----\nMIIDHTCCAqOgAwIBAgIUVqjgtJqf4hUYJkqdYzi+0xwhwFYwCgYIKoZIzj0EAwMw\nXDEeMBwGA1UEAwwVUElEIElzc3VlciBDQSAtIFVUIDAxMS0wKwYDVQQKDCRFVURJ\nIFdhbGxldCBSZWZlcmVuY2UgSW1wbGVtZW50YXRpb24xCzAJBgNVBAYTAlVUMB4X\nDTIzMDkwMTE4MzQxN1oXDTMyMTEyNzE4MzQxNlowXDEeMBwGA1UEAwwVUElEIElz\nc3VlciBDQSAtIFVUIDAxMS0wKwYDVQQKDCRFVURJIFdhbGxldCBSZWZlcmVuY2Ug\nSW1wbGVtZW50YXRpb24xCzAJBgNVBAYTAlVUMHYwEAYHKoZIzj0CAQYFK4EEACID\nYgAEFg5Shfsxp5R/UFIEKS3L27dwnFhnjSgUh2btKOQEnfb3doyeqMAvBtUMlClh\nsF3uefKinCw08NB31rwC+dtj6X/LE3n2C9jROIUN8PrnlLS5Qs4Rs4ZU5OIgztoa\nO8G9o4IBJDCCASAwEgYDVR0TAQH/BAgwBgEB/wIBADAfBgNVHSMEGDAWgBSzbLiR\nFxzXpBpmMYdC4YvAQMyVGzAWBgNVHSUBAf8EDDAKBggrgQICAAABBzBDBgNVHR8E\nPDA6MDigNqA0hjJodHRwczovL3ByZXByb2QucGtpLmV1ZGl3LmRldi9jcmwvcGlk\nX0NBX1VUXzAxLmNybDAdBgNVHQ4EFgQUs2y4kRcc16QaZjGHQuGLwEDMlRswDgYD\nVR0PAQH/BAQDAgEGMF0GA1UdEgRWMFSGUmh0dHBzOi8vZ2l0aHViLmNvbS9ldS1k\naWdpdGFsLWlkZW50aXR5LXdhbGxldC9hcmNoaXRlY3R1cmUtYW5kLXJlZmVyZW5j\nZS1mcmFtZXdvcmswCgYIKoZIzj0EAwMDaAAwZQIwaXUA3j++xl/tdD76tXEWCikf\nM1CaRz4vzBC7NS0wCdItKiz6HZeV8EPtNCnsfKpNAjEAqrdeKDnr5Kwf8BA7tATe\nhxNlOV4Hnc10XO1XULtigCwb49RpkqlS2Hul+DpqObUs\n-----END CERTIFICATE-----", "profile": "openid4vp" } ``` ### Response #### Success Response (200) - **transaction_id** (string) - The unique identifier for the transaction. - **client_id** (string) - The client identifier. - **request_uri** (string) - The URI for the transaction request. - **request_uri_method** (string) - The HTTP method for the request URI. #### Response Example ```json { "transaction_id": "STMMbidoCQTtyk9id5IcoL8CqdC8rxgks5FF8cqqUrHvw0IL3AaIHGnwxvrvcEyUJ6uUPNdoBQDa7yCqpjtKaw", "client_id": "x509_san_dns:localhost", "request_uri": "https://localhost:8080/wallet/request.jwt/5N6E7VZsmwXOGLz1Xlfi96MoyZVC3FZxwdAuJ26DnGcan-vYs-VAKErioQ58BWEsKlVw2_X49jpZHyp0Mk9nKw", "request_uri_method": "post" } ``` ``` -------------------------------- ### Verifier UI Flow (Same-Device) Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/_autodocs/README.md Illustrates the sequence of API calls for the same-device presentation flow, starting from the Verifier UI initiating a transaction to displaying the final result. ```text Verifier UI ↓ POST /ui/presentations → generates QR code ↓ (User scans with wallet) Wallet ↓ GET /wallet/request.jwt/{requestId} ↓ (User selects credentials) POST /wallet/direct_post/{requestId} ↓ Verifier processes response ↓ GET /ui/presentations/{transactionId} → polling returns vp_token ↓ Verifier UI displays result ``` -------------------------------- ### Poll with Response Code Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/_autodocs/api-reference/04-get-wallet-response.md This example shows how to poll for a wallet response when a specific response code is provided. This is useful for scenarios where the wallet might return different responses based on a code. ```APIDOC ## Poll with Response Code ### Description This example shows how to poll for a wallet response when a specific response code is provided. This is useful for scenarios where the wallet might return different responses based on a code. ### Method GET (or equivalent polling mechanism) ### Endpoint `/verifier/endpoint/response/{transactionId}?response_code={responseCode}` ### Parameters #### Path Parameters - **transactionId** (TransactionId) - Required - The unique identifier for the presentation transaction. #### Query Parameters - **response_code** (ResponseCode) - Required - The specific response code to filter the results. ### Request Example ```kotlin val transactionId = TransactionId("txn-xyz789") val responseCode = ResponseCode("response-code-123") // From wallet val result = getWalletResponse(transactionId, responseCode) when (result) { is QueryResponse.Found -> { // Response available val response = result.value return ResponseEntity.ok().body(response) } is QueryResponse.InvalidState -> { // Response code doesn't match or not ready // Tell UI to retry return ResponseEntity.status(HttpStatus.ACCEPTED).build() } is QueryResponse.NotFound -> { return ResponseEntity.notFound().build() } } ``` ### Response #### Success Response (200 OK) - **value** (WalletResponse) - The wallet response matching the provided response code. #### Response Example ```json { "vpToken": "eyJ...", "error": null, "errorDescription": null } ``` #### Response Example (Accepted - Retry) - Returns an `ACCEPTED` status if the response code does not match or the state is invalid, indicating the client should retry. #### Error Response (404 Not Found) - Indicates the transaction is unknown or expired. ``` -------------------------------- ### Configure HTTP Proxy Password Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/README.md Set the VERIFIER_HTTP_PROXY_PASSWORD environment variable to provide a password for authenticating against the HTTP proxy. Example: passwd. ```bash export VERIFIER_HTTP_PROXY_PASSWORD="passwd" ``` -------------------------------- ### Configure HTTP Proxy Username Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/README.md Set the VERIFIER_HTTP_PROXY_USERNAME environment variable to provide a username for authenticating against the HTTP proxy. Example: username. ```bash export VERIFIER_HTTP_PROXY_USERNAME="username" ``` -------------------------------- ### Spring WebFlux Handler Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/_autodocs/api-reference/04-get-wallet-response.md This example demonstrates how to implement the GetWalletResponse functionality within a Spring WebFlux application, handling different response types from the `getWalletResponse` function. ```APIDOC ## Spring WebFlux Handler ### Description This example demonstrates how to implement the GetWalletResponse functionality within a Spring WebFlux application, handling different response types from the `getWalletResponse` function. ### Method GET ### Endpoint `/verifier/endpoint/response/{transactionId}` (with optional `response_code` query parameter) ### Parameters #### Path Parameters - **transactionId** (string) - Required - The unique identifier for the presentation transaction. #### Query Parameters - **response_code** (string) - Optional - The specific response code to filter the results. ### Request Example ```kotlin suspend fun handleGetWalletResponse(req: ServerRequest): ServerResponse { val transactionId = TransactionId(req.pathVariable("transactionId")) val responseCode = req.queryParam("response_code") .map { ResponseCode(it) } .orElse(null) logger.info("Retrieving wallet response for tx: ${transactionId.value}") return when (val result = getWalletResponse(transactionId, responseCode)) { is QueryResponse.NotFound -> { ServerResponse.notFound().buildAndAwait() } is QueryResponse.InvalidState -> { ServerResponse.badRequest().buildAndAwait() } is QueryResponse.Found -> { ServerResponse.ok() .contentType(MediaType.APPLICATION_JSON) .bodyValueAndAwait(result.value) } } } ``` ### Response #### Success Response (200 OK) - Returns the wallet response JSON if found. #### Error Response (404 Not Found) - Returned if the transaction is not found or has expired. #### Error Response (400 Bad Request) - Returned if the presentation is in an invalid state (e.g., not ready yet). ``` -------------------------------- ### Example Exponential Backoff for Polling Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/_autodocs/api-reference/04-get-wallet-response.md Demonstrates an exponential backoff strategy for polling the wallet for a response. It includes logic for handling different `QueryResponse` states and network errors, with a maximum number of attempts and a delay cap. ```kotlin var delay = 1000L // 1 second var attempt = 0 while (attempt < 60) { try { val result = getWalletResponse(transactionId, null) when (result) { is QueryResponse.Found -> return result.value is QueryResponse.InvalidState -> { // Continue polling attempt++ Thread.sleep(delay) delay = minOf(delay * 2, 10000L) // Cap at 10 seconds } is QueryResponse.NotFound -> throw TransactionExpiredException() } } catch (e: Exception) { // Network error; retry Thread.sleep(delay) delay = minOf(delay * 2, 10000L) } } throw TimeoutException("No response after $attempt attempts") ``` -------------------------------- ### Poll for Presentation Result (Success) Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/_autodocs/api-reference/04-get-wallet-response.md This example demonstrates how to poll for the wallet response using a transaction ID. It handles the success case where the presentation is completed and extracts the VP Token or any errors returned by the wallet. ```APIDOC ## Poll for Presentation Result (Success) ### Description This example demonstrates how to poll for the wallet response using a transaction ID. It handles the success case where the presentation is completed and extracts the VP Token or any errors returned by the wallet. ### Method GET (or equivalent polling mechanism) ### Endpoint `/verifier/endpoint/response/{transactionId}` ### Parameters #### Path Parameters - **transactionId** (TransactionId) - Required - The unique identifier for the presentation transaction. #### Query Parameters - **response_code** (ResponseCode) - Optional - A code returned by the wallet to filter the response. ### Request Example ```kotlin val getWalletResponse: GetWalletResponse = // injected val transactionId = TransactionId("txn-abc123") val result = getWalletResponse(transactionId, null) when (result) { is QueryResponse.Found -> { val walletResponse = result.value if (walletResponse.error != null) { // Wallet returned error println("Error: ${walletResponse.error}") println("Description: ${walletResponse.errorDescription}") } else { // Wallet submitted credentials val vpToken = walletResponse.vpToken println("VP Token: $vpToken") // Process credentials... } // Return to verifier UI return ResponseEntity.ok().body(walletResponse) } is QueryResponse.NotFound -> { // Transaction expired or doesn't exist return ResponseEntity.notFound().build() } is QueryResponse.InvalidState -> { // Still waiting for wallet response return ResponseEntity.badRequest().build() } } ``` ### Response #### Success Response (200 OK) - **value** (WalletResponse) - The wallet response containing VP Token or error details. #### Response Example ```json { "vpToken": "eyJ...", "error": null, "errorDescription": null } ``` #### Error Response (404 Not Found) - Indicates the transaction is unknown or expired. #### Error Response (400 Bad Request) - Indicates the presentation is in an in-progress or initial state and not ready yet. ``` -------------------------------- ### Configure Verifier Service in Docker Compose Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/README.md Example Docker Compose configuration for the verifier service. Set environment variables to configure its behavior, such as the public URL and response mode. Ensure the image is updated to the latest version from ghcr.io. ```yaml verifier: image: ghcr.io/eu-digital-identity-wallet/eudi-srv-verifier-endpoint:latest container_name: verifier-backend ports: - "8080:8080" environment: VERIFIER_PUBLICURL: "https://10.240.174.10" VERIFIER_RESPONSE_MODE: "DirectPost" VERIFIER_ACCESS_CERTIFICATE_KEYSTORE: file:///keystore.jks ``` -------------------------------- ### Get authorization request (GET) Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/README.md Retrieves an authorization request JWT when the request_uri_method is GET. This endpoint is used by the wallet to fetch the authorization request details referenced by a request_uri. ```APIDOC ## GET /wallet/request.jwt/{requestId} ### Description An endpoint to be used by wallet when the OpenId4VP authorization request is passed to wallet by reference as a request_uri, using the GET method. ### Method GET ### Endpoint http://localhost:8080/wallet/request.jwt/{requestId} ### Parameters #### Path Parameters - **requestId** (string) - Required - The identifier of the authorization request ### Request Example ```bash curl https://localhost:8080/wallet/request.jwt/5N6E7VZsmwXOGLz1Xlfi96MoyZVC3FZxwdAuJ26DnGcan-vYs-VAKErioQ58BWEsKlVw2_X49jpZHyp0Mk9nKw ``` ### Response #### Success Response - The authorization request payload as a signed JWT. ``` -------------------------------- ### Get Authorization Request (GET) Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/README.md Use this endpoint when the OpenId4VP authorization request is passed by reference using `request_uri_method` GET. It retrieves the authorization request payload as a signed JWT. ```bash curl https://localhost:8080/wallet/request.jwt/5N6E7VZsmwXOGLz1Xlfi96MoyZVC3FZxwdAuJ26DnGcan-vYs-VAKErioQ58BWEsKlVw2_X49jpZHyp0Mk9nKw ``` -------------------------------- ### Get Wallet Request (JWT) Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/_autodocs/MANIFEST.md Retrieves a wallet request object, identified by a request ID, using the GET method. ```APIDOC ## GET /wallet/request.jwt/{requestId} (request GET) ### Description Retrieves a wallet request object in JWT format, identified by its request ID. ### Method GET ### Endpoint /wallet/request.jwt/{requestId} ### Parameters #### Path Parameters - **requestId** (string) - Required - The unique identifier for the request. ``` -------------------------------- ### Get wallet response Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/README.md Retrieves the wallet's submitted response for a given transaction. This endpoint is used by the verifier to get the presentation response from the wallet. ```APIDOC ## GET /ui/presentations/{transactionId} ### Description Retrieves the wallet submitted response as JSON. This endpoint is used by the verifier to get the presentation response from the wallet. ### Method GET ### Endpoint http://localhost:8080/ui/presentations/{transactionId} ### Parameters #### Path Parameters - **transactionId** (string) - Required - The initialized transaction's identifier #### Query Parameters - **responseCode** (string) - Optional - Response code generated in case of 'same device' case ### Request Example ```bash curl http://localhost:8080/ui/presentations/5N6E7VZsmwXOGLz1Xlfi96MoyZVC3FZxwdAuJ26DnGcan-vYs-VAKErioQ58BWEsKlVw2_X49jpZHyp0Mk9nKw?response_code=5272d373-ebab-40ec-b44d-0a9909d0da69 ``` ### Response #### Success Response - The wallet submitted response as JSON. ``` -------------------------------- ### Configure External Keystore with Docker Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/_autodocs/configuration.md Set up an external keystore for the verifier endpoint by mounting the keystore file and configuring relevant environment variables. This allows the verifier to use custom certificates and keys. ```bash docker run \ -e VERIFIER_ACCESS_CERTIFICATE_KEYSTORE=file:///certs/keystore.jks \ -e VERIFIER_ACCESS_CERTIFICATE_KEYSTORE_PASSWORD=yourpassword \ -e VERIFIER_ACCESS_CERTIFICATE_ALIAS=your_alias \ -e VERIFIER_ACCESS_CERTIFICATE_PASSWORD=your_cert_password \ -v /path/to/keystore.jks:/certs/keystore.jks:ro \ ghcr.io/eu-digital-identity-wallet/eudi-srv-verifier-endpoint:latest ``` -------------------------------- ### Get Wallet Response Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/README.md This GET endpoint is used by the Verifier to retrieve the wallet's submitted response. It requires the transaction ID and optionally a response code for same-device scenarios. ```bash curl http://localhost:8080/ui/presentations/5N6E7VZsmwXOGLz1Xlfi96MoyZVC3FZxwdAuJ26DnGcan-vYs-VAKErioQ58BWEsKlVw2_X49jpZHyp0Mk9nKw?response_code=5272d373-ebab-40ec-b44d-0a9909d0da69 ``` -------------------------------- ### GET Request to Retrieve Request Object Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/_autodocs/api-reference/02-retrieve-request-object.md Use this snippet to perform a GET request to retrieve an authorization request object. It handles successful retrieval and specific error cases like 'PresentationNotFound' and 'InvalidState'. ```kotlin val retrieveRequestObject: RetrieveRequestObject = // injected val requestId = RequestId("req-abc123") val method = RetrieveRequestObjectMethod.Get try { val jwt = retrieveRequestObject(requestId, method) // Return JWT to wallet return ResponseEntity.ok() .contentType(MediaType("application", "oauth-authz-req+jwt")) .body(jwt) } catch (error: RetrieveRequestObjectError) { return when (error) { RetrieveRequestObjectError.PresentationNotFound -> { ResponseEntity.notFound().build() } is RetrieveRequestObjectError.InvalidState -> { ResponseEntity.badRequest().build() } else -> { ResponseEntity.status(HttpStatus.BAD_REQUEST).build() } } } ``` -------------------------------- ### Build Verifier Service Docker Image Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/README.md Use this command to create a local Docker image of the service. This is useful for containerized deployments or testing. ```bash ./gradlew bootBuildImage ``` -------------------------------- ### Spring WebFlux Handler for Get Wallet Response Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/_autodocs/api-reference/04-get-wallet-response.md A suspend function for handling GET requests to retrieve the wallet response in a Spring WebFlux application. It extracts transaction ID and optional response code from the request and returns the appropriate ServerResponse based on the query result. ```kotlin suspend fun handleGetWalletResponse(req: ServerRequest): ServerResponse { val transactionId = TransactionId(req.pathVariable("transactionId")) val responseCode = req.queryParam("response_code") .map { ResponseCode(it) } .orElse(null) logger.info("Retrieving wallet response for tx: ${transactionId.value}") return when (val result = getWalletResponse(transactionId, responseCode)) { is QueryResponse.NotFound -> { ServerResponse.notFound().buildAndAwait() } is QueryResponse.InvalidState -> { ServerResponse.badRequest().buildAndAwait() } is QueryResponse.Found -> { ServerResponse.ok() .contentType(MediaType.APPLICATION_JSON) .bodyValueAndAwait(result.value) } } } ``` -------------------------------- ### Get Presentation Events Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/_autodocs/MANIFEST.md Retrieves the event log for a specific presentation transaction. ```APIDOC ## GET /ui/presentations/{transactionId}/events (event log) ### Description Retrieves the event log associated with a specific presentation transaction. ### Method GET ### Endpoint /ui/presentations/{transactionId}/events ### Parameters #### Path Parameters - **transactionId** (string) - Required - The unique identifier for the presentation transaction. ``` -------------------------------- ### Initialize and Poll for Presentation (JavaScript/TypeScript) Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/_autodocs/README.md This snippet demonstrates how to initialize a presentation request from the frontend and poll for the result. It handles the initial POST request and subsequent polling for the VP token. ```javascript // Initialize transaction const response = await fetch('/ui/presentations', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ nonce: 'unique-nonce', presentation_definition: { /* DCQL */ }, }), }); const { transaction_id, authorization_request_uri } = await response.json(); // Poll for result const pollResult = async () => { const res = await fetch(`/ui/presentations/${transaction_id}`); if (res.status === 200) { return await res.json(); // { vp_token: {...} } } // retry }; ``` -------------------------------- ### Get presentation event log Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/README.md Retrieves the log of notable events for a specific presentation transaction. ```APIDOC ## GET /ui/presentations/{transactionId}/events ### Description Retrieves the log of notable events for a specific presentation. ### Method GET ### Endpoint http://localhost:8080/ui/presentations/{transactionId}/events ### Parameters #### Path Parameters - **transactionId** (string) - Required - The initialized transaction's identifier ### Response #### Success Response (200) - **events** (array) - The log of notable events for the specific presentation. ``` -------------------------------- ### Initialize Transaction (Kotlin) Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/_autodocs/README.md Use this snippet to initiate a transaction from the backend. Ensure the InitTransaction dependency is injected. ```kotlin val initTransaction: InitTransaction = // injected val request = InitTransactionTO( nonce = "unique-nonce", presentationDefinition = buildJsonObject { /* DCQL */ }, output = Output.Json, ) when (val response = initTransaction(request)) { is InitTransactionResponse.JwtSecuredAuthorizationRequestTO -> { // Return transaction ID to verifier UI return mapOf("transactionId" to response.transactionId) } } ``` -------------------------------- ### Get Wallet Presentation Response Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/_autodocs/MANIFEST.md Retrieves the wallet's response for a given presentation transaction. ```APIDOC ## GET /ui/presentations/{transactionId} (wallet response) ### Description Retrieves the wallet's response for a specific presentation transaction identified by its ID. ### Method GET ### Endpoint /ui/presentations/{transactionId} ### Parameters #### Path Parameters - **transactionId** (string) - Required - The unique identifier for the presentation transaction. ``` -------------------------------- ### Initialize Transaction with Presentation Definition URI Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/_autodocs/api-reference/01-init-transaction.md Initializes a transaction using a remote presentation definition URI. The `presentationDefinitionResolveOnServer` flag should be set to true to ensure the definition is resolved server-side. The response includes the authorization URI. ```kotlin val request = InitTransactionTO( nonce = "remote-def-123", presentationDefinitionUri = "https://issuer.example.com/definitions/pid-request", presentationDefinitionResolveOnServer = true, // Resolve on server output = Output.Json, ) when (val result = initTransaction(request)) { is InitTransactionResponse.JwtSecuredAuthorizationRequestTO -> { println("Definition resolved and transaction created") println("Authorization URI: ${result.authorizationRequestUri}") } else -> {} } ``` -------------------------------- ### Minimal DCQL Request (JSON Response) Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/_autodocs/api-reference/01-init-transaction.md Use this snippet to initiate a transaction with a minimal DCQL request, expecting a JSON response containing transaction details. Ensure `InitTransaction` is injected and the `request` object is properly constructed. ```kotlin val initTransaction: InitTransaction = // injected val request = InitTransactionTO( nonce = "abc123", presentationDefinition = buildJsonObject { put("id", "pid-request") putJsonArray("credentials") { add(buildJsonObject { put("id", "pid") put("format", "mso_mdoc") put("doctype", "eu.europa.ec.eudi.pid.1") }) } }, output = Output.Json, ) val result = initTransaction(request) when (result) { is InitTransactionResponse.JwtSecuredAuthorizationRequestTO -> { println("Transaction: ${result.transactionId}") println("Client ID: ${result.clientId}") println("Request URI: ${result.requestUri}") println("URI Method: ${result.requestUriMethod}") // Return transactionId and authorizationRequestUri to verifier UI } is InitTransactionResponse.QrCode -> { // Handle QR code image } } ``` -------------------------------- ### Get Wallet Public Keys (JWK Set) Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/_autodocs/MANIFEST.md Retrieves the wallet's public keys in JWK Set format. ```APIDOC ## GET /wallet/public-keys.json (JWK set) ### Description Retrieves the wallet's public keys, formatted as a JSON Web Key (JWK) Set. ### Method GET ### Endpoint /wallet/public-keys.json ### Response #### Success Response (200) - **keys** (array) - An array of JWK objects representing the wallet's public keys. ``` -------------------------------- ### Create a new branch for changes Source: https://github.com/eu-digital-identity-wallet/eudi-srv-verifier-endpoint/blob/main/CONTRIBUTING.md Follow these commands to create a new branch from main for your contributions. ```bash git checkout main git pull git checkout -b my-branch ```