SpruceKit
SpruceID
  • 🌲SpruceKit Introduction
    • Decentralized Identity Overview
    • Glossary
  • ⚡Quickstart
  • SpruceKit Mobile
    • SpruceKit Showcase App
      • Installation
      • Getting Started
      • Issue a Showcase Credential
      • Present a Showcase Credential
    • SpruceKit Mobile SDK
      • Introduction
      • Core Components
        • StorageManager
        • KeyManager
        • CredentialPack
        • Card
        • IsoMdlPresentation
        • mDocReader/IsomDLReader
        • Document Scanner
      • SpruceKit iOS SDK
        • Installation
        • Build a Wallet
          • Accept a W3C VC
          • Present a W3C VC
          • Present mDL in-person/offline
          • Present an mDL over the internet
        • Build a Verifier
          • Verify a W3C VC
          • Verify an mDL in-person/offline
          • Verify an mDL over the internet
      • SpruceKit Android SDK
        • Installation
        • Build a Wallet
          • Accept a W3C VC
          • Present a W3C VC
          • Present an mDL in-person/offline
          • Present an mDL over the internet
        • Build a Verifier
          • Verify a W3C VC
          • Verify an mDL in-person/offline
          • Verify an mDL over the internet
  • Verifiable Digital Credentials
    • ⚙️DIDKit
      • Installation
      • Core Concepts
      • DID Methods
      • Runtime Configuration
      • Specifications and Dependencies
      • Quickstart
      • DIDKit Packages
        • Command Line Interface
        • HTTP Server
        • Rust Crate
        • C Interface
        • Java and Android
        • Python
        • Javascript
      • DIDKit Examples
        • Core Functions (CLI)
        • Core Functions (HTTP)
        • did-web in minutes
        • Batch Generation & Verification
    • 🪪ISO mDL
      • Quickstart
      • Core Concepts
      • User Guide
  • Schema Definition Language
    • 🔗TreeLDR
      • TreeLDR Quickstart
        • First Schema
        • Compilation into JSON Schema
        • Compilation into JSON-LD Context
        • Writing a Layout
        • Simple Rust Integration
      • Types
        • Literal Types
      • Layouts
        • Primitive Layouts
        • Literal Layouts
        • Enumeration
        • Array Layout
        • References
      • Compiling
        • Schema Definition Formats
          • JSON Schema
          • JSON-LD Context
          • Resource Description Framework (RDF)
        • Programming Languages
          • Compiling to Rust
      • RDF Vocabulary
      • 💡TreeLDR Basics
        • Types and Layouts
        • Properties
        • Syntax
  • Witness for Credential Claims
    • 🔭Rebase
      • Core Library
      • Rust Client/Witness SDK
      • WASM Client SDK
      • Simple "Basic Post" Schema
      • DNS Witness Flow Schema
  • References
    • Contributing
    • Code of Conduct
Powered by GitBook
On this page
  • 1. Scanning Documents
  • Verify mdocs
  • BLESessionStateDelegate

Was this helpful?

  1. SpruceKit Mobile
  2. SpruceKit Mobile SDK
  3. SpruceKit Android SDK
  4. Build a Verifier

Verify an mDL in-person/offline

Verify an ISO/IEC 18013-5 mDL over BlueTooth Low Energy

PreviousVerify a W3C VCNextVerify an mDL over the internet

Last updated 3 months ago

Was this helpful?

This guide is for Android applications. Building for iOS? Look here: Verify an mDL in-person/offline

The structure for verifying an mDL is very similar to implementing the . To verify an mDL over BLE you will need to manage the BLEReaderSessionState and provide a UI for every state during the presentation process.

1. Scanning Documents

Rather than generating a QR-code, for a verifier, you will have to implement a scanning ability. For mdoc verification, you can directly use the QRCodeScanner. If you want to implement a generic scanner that can handle PDF417 VC Barcodes and Machine Readable Zones, check out this example of a .

Verify mdocs

Here, we give an example of what your VerifyMdocView could look like. You can also directly reference our implementation.

@Composable
fun MdocReaderView(
) {
    val context = LocalContext.current
    var reader: IsoMdlReader? = null

    var scanProcessState by remember {
        mutableStateOf(State.SCANNING)
    }

    var result by remember {
        mutableStateOf<Map<String, Map<String, MDocItem>>?>(null)
    }


    fun elementMapToList(elements: Map<String, Map<String, Boolean>>): List<String> {
        val elementList = listOf(elements.values.map { it.keys.toList() })
        return elementList.flatten().flatten()
    }

    fun onRead(content: String) {
        scanProcessState = State.TRANSMITTING
        checkAndRequestBluetoothPermissions(
            context,
            getPermissions().toTypedArray(),
            launcherMultiplePermissions
        )
        val bluetooth = getBluetoothManager(context)
        GlobalScope.launch {
            reader = IsoMdlReader(
                // Your BleSessionStateDelegate implementation. See the next code block!
                <bleCallback>,
                // The scanned value
                content,
                // Define the items you want to query by namespace, attribute_name 
                // and intent to retain:
                <defaultElements>,
                // Enter an array of issuer certificates that you accept (e.g. a list of US states).
                // These issuer certificates should follow the IACA profile as defined in ISO/IEC 18013-5 Annex B.
                <trustAnchorCerts>,
                // the Bluetooth manager
                <bluetooth>,
                // The local app context
                context
            )
        }
    }

    fun back() {
        navController.navigate(
            Screen.HomeScreen.route.replace("{tab}", "verifier")
        ) {
            popUpTo(0)
        }
    }

    val elementsList = elementMapToList(defaultElements)

    when (scanProcessState) {
        // Manage the UI based on the ProcessState here.
}

BLESessionStateDelegate

Build the Delegate that holds the BLEReaderSessionState and the mDocReader sessionManager. The update method on the bleCallback will handle the response, using the IsomDlReader component.

// Define your BLE Session State delegate

    val bleCallback: BLESessionStateDelegate = object : BLESessionStateDelegate() {
        override fun update(state: Map<String, Any>) {
            Log.d("VerifyMDocView", state.toString())
            if (state.containsKey("mdl")) {
                result = reader?.handleResponse(state["mdl"] as ByteArray)
                scanProcessState = State.DONE
            }
        }

        override fun error(error: Exception) {
            // Your error implementation
        }
    }

Once you have your Delegate implemented, you can call it from your MdocReaderView, which manages the UI based on the SessionState.

There you have it, you now have everything you need for an mDL verification flow. You can:

  • Initiate a QR Code Scanner

  • Manage the states of the BleReaderSession with the appropriate UI of your design

  • Configure your own TrustAnchors

  • Call the MdocReader component to verify the mdoc

presentation of an mDL
Scanning Component
example