From 701c375e3ee027c8eb924e202de88f982d7da619 Mon Sep 17 00:00:00 2001 From: abhip2565 Date: Tue, 7 Jul 2026 16:04:00 +0530 Subject: [PATCH 1/7] docs(inji-mobile): rewrite workflow customization for Inji 1.x Rework the Inji Wallet workflow customization page to reflect the release 1.x modular XState architecture: root/service-actor wiring, the per-feature file convention (Model/Machine/Actions/Guards/Services/Selectors), an up-to-date machine reference grouped by capability, and practical guidance for extending or adding machines. Signed-off-by: abhip2565 --- .../workflow-customization.md | 249 ++++++++++++++---- 1 file changed, 192 insertions(+), 57 deletions(-) diff --git a/inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md b/inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md index b8e3541..de91035 100644 --- a/inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md +++ b/inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md @@ -1,99 +1,234 @@ -# Workflow customization +# Workflow Customization -Workflow in Inji Wallet is achieved by finite-state machine components. State machines are written using a library called [xstate](https://xstate.js.org/docs/recipes/react.html). All the state machines are available in the machines folder of the Inji Wallet codebase. There are few machines under the screens folder but these are too specific to those features. +## Overview -Here is a list of state machines and their responsibilities. The developers can choose to use the existing state machine components and customize the workflow as per their needs. +Every user journey in **Inji Wallet** (release **1.x**) — onboarding, downloading a credential, sharing it online or offline, backing it up, logging in with a QR code — is modelled as a **finite‑state machine (FSM)**. Modelling flows as state machines keeps the behaviour explicit and predictable: at any point in time the app is in exactly one well‑defined state, and it can only move to another state in response to a known event. -## app.ts +The state machines are written with [**XState v4**](https://xstate.js.org/docs/) (`xstate@^4.35.0`) and live in the [`machines/`](https://github.com/mosip/inji-wallet/tree/master/machines) folder of the Inji Wallet codebase. A few very screen‑specific machines live under `screens/`, but the reusable, customizable workflow logic is concentrated in `machines/`. -This is the root state machine for the application. On initialisation, it starts other state machines from: +Implementers can reuse the existing machines as‑is, extend them (add states, actions, guards, or services), or replace a whole flow with their own machine — this page explains how the machines are structured and wired together so you can do that confidently. -* store.ts -* auth.ts -* vcMetaMachine.ts -* settings.ts -* activityLog.ts -* requestMachine.ts -* scanMachine.ts -* backup.ts -* backupRestore.ts +{% hint style="info" %} +XState is a data structure + interpreter. Editing a machine is mostly editing a plain JavaScript object (the state chart) plus its associated `actions`, `guards`, and `services`. You rarely need to touch the React screens to change a workflow — you change the machine that drives them. +{% endhint %} -## store.ts +## How the machines are wired together -This state machine takes care of actions related to storing and retrieving data on the mobile phone. It exposes the wrapper to all the other state machines to work with data stored on the device. +Inji Wallet uses a **multi‑actor** architecture. A root machine boots the app and **spawns** long‑lived child machines ("service actors"). These references are kept in a shared context object (`AppServices`, exposed through `shared/GlobalContext`) so any part of the app can `send` events to any machine. -It also performs the custom encryption and decryption required for saving and retrieving data from the underlying store. +``` +app.ts (root) + │ + ├── store → machines/store.ts (spawned first — storage/crypto gateway) + │ + └── on READY, spawns the service actors ────────────────────────────── + ├── auth → machines/auth.ts + ├── vcMeta → machines/VerifiableCredential/VCMetaMachine + │ └── spawns one vcItem per credential → VCItemMachine + ├── settings → machines/settings.ts + ├── activityLog → machines/activityLog.ts + ├── backup → machines/backupAndRestore/backup + ├── backupRestore → machines/backupAndRestore/restore + ├── scan → machines/bleShare/scan (offline share – sender) + └── request → machines/bleShare/request (Android only – offline receive) +``` -As of now, the store state machine uses following two libraries which abstracts how the data is stored between iOS and Android: +Machines that are spawned **on demand** (not at boot) include: -* [react-native-mmkv-storage](https://github.com/ammarahm-ed/react-native-mmkv-storage) - stores all the meta information and references of the encrypted VC. -* [react-native-fs](https://www.npmjs.com/package/react-native-fs) - stores the encrypted VC as a separate file, +* `IssuersMachine` — the OpenID4VCI download journey, driven from the Issuers/Home screen. +* `openID4VPMachine` — online sharing (OpenID4VP), spawned by `IssuersMachine`/sharing flows. +* `QrLoginMachine` — "Login with QR code" (OpenID Connect), spawned from the scanner. +* `faceScanner`, `pinInput`, `biometrics` — utility machines used inside other flows. -## auth.ts +### The factory‑and‑spawn pattern -This state machine helps to set up authentication for the application. It allows users to choose between biometric and passcode-based authentication on the first launch. It also updates the app state as authorized or unauthorized based on user action on first launch. +Every service machine exports a **factory function** `createXMachine(serviceRefs)` alongside the machine instance. `app.ts` calls the factory with the current `serviceRefs` and `spawn`s it, so the child machine can reach its siblings: -On first launch, once the user selects language preference, and goes through intro sliders, user has been asked to choose the unlock method. +```ts +// machines/app.ts (excerpt) +serviceRefs.vcMeta = spawn( + createVcMetaMachine(serviceRefs), + vcMetaMachine.id, +); +``` -After selecting the unlock method as passcode or biometric, the user is navigated to Home screen Once user is on home screen, app state is considered as authorized. Once a user logs out from settings, the state is considered as unauthorized. +### How machines talk to each other -## vcItemMachine.ts +* **Parent → child:** `send(EVENT, { to: context.serviceRefs. })`. +* **Child → parent:** `sendParent(EVENT)`. +* **App‑wide broadcasts:** `app.ts` forwards lifecycle changes (focus/blur, online/offline) to every service actor by re‑emitting the event with an `APP_` prefix (see the `forwardToServices` action). So a child machine can react to `APP_ONLINE`, `APP_OFFLINE`, `APP_ACTIVE`, etc. +* **Storage:** no machine touches the disk directly. They all send `StoreEvents.GET/SET/…` to the `store` actor, which centralises encryption/decryption and persistence. -This state machine is spawned for every VC downloaded, and tracks its lifecycle. This contains all the activities/state related to VC like: +## Anatomy of a machine (the file convention) -* load VC -* activate VC -* activate/delete/pin/unpin VC -* verifies the credentials +Simple machines are a single file (e.g. `auth.ts`, `settings.ts`). The larger flows follow a **modular convention** — one folder per feature, with responsibilities split across files. Taking `machines/Issuers/` as the reference: -## vcMetaMachine.ts +| File | Responsibility | +| --- | --- | +| `IssuersModel.ts` | Declares the machine **context** (data) and the **events** it accepts, using `createModel(...)`. This is the type‑safe contract for the machine. | +| `IssuersMachine.ts` | The **state chart** — states, transitions, `initial` state, invoked services. Wires in the actions/guards/services below. | +| `IssuersActions.ts` | Pure `assign`/side‑effect **actions** that mutate context or fire effects. | +| `IssuersGuards.ts` | **Guard** (condition) functions used in `cond:` to choose between transitions. | +| `IssuersService.ts` | **Services** — the async work (API calls, crypto, SDK calls) invoked by states. | +| `IssuersSelectors.ts` | **Selectors** — read helpers that components use to derive UI state from the machine. | +| `IssuersEvents.ts` | Shared event creators (when events are reused across files). | +| `*.typegen.ts` | **Auto‑generated** type‑safety helpers for XState. Do not edit by hand (see [Keep typegen in sync](#2-keep-typegen-in-sync-after-editing)). | -This state machine takes care of the all the meta information related to all VCs. +The single‑file machines (`auth.ts`, `store.ts`, `settings.ts`, …) keep the same building blocks (`model`, `states`, `actions`, `guards`, `services`) inline within one file. -## issuersMachine.ts +{% hint style="info" %} +Many machine files begin with an `@xstate-layout` comment. That hash is used by the [Stately](https://stately.ai/) / [XState VS Code](https://marketplace.visualstudio.com/items?itemName=statelyai.stately-vscode) visual editor to render and round‑trip the chart. You can paste a machine into the [XState Visualizer](https://stately.ai/viz) to see and edit the flow graphically. +{% endhint %} -This state machine list of issuers in the user interface, as well as downloads and caches the issuer's configuration. It also performs the following actions: +## Machine reference -* download credential -* verify the verifiable credential -* store the verifiable credential +The machines are grouped below by the capability they power. -## backup.ts +### Bootstrap & core -This state machine performs all action related to backing up of the verifiable credentials on google drive or iCloud. +#### `app.ts` -## backupRestore.ts +The **root** machine. On start it first spawns `store`, checks/generates cryptographic key pairs, fetches remote configuration (cache TTL and other properties via Mimoto's `allProperties` API), loads the credential‑registry and eSignet host from storage, and only then spawns the remaining service actors and moves to the `ready` (parallel) state. In `ready` it continuously tracks **app focus** and **network** status and broadcasts them to all children. It also handles deep links for QR login, OpenID4VP, and credential offers. -This state machine performs all action related to restoring and verifying the backed up verifiable credentials from google drive or iCloud. +#### `store.ts` -## settings.ts +The single gateway for all persistence. It exposes `GET`/`SET`/`APPEND`/`REMOVE`/`CLEAR` style events to the rest of the app and performs the **encryption/decryption** for data at rest. It abstracts the underlying storage engines: -This state machine helps to show contents and interactions on the settings screen of the application. This facilitates options like language switch, enable/disable biometric unlock etc. +* [`react-native-mmkv-storage`](https://github.com/ammarahm-ed/react-native-mmkv-storage) — stores metadata and references to encrypted VCs. +* [`react-native-fs`](https://www.npmjs.com/package/react-native-fs) — stores each encrypted VC as a separate file. -## activityLog +Key material is held in the hardware‑backed keystore (see [Secure Keystore](../integration-guide/secure-keystore.md)). -This state machine helps to view the audit log of the different activities on the application and shows it on a separate screen. Some of the activities that are shown are VC download, VC receive, VC sent events etc. +#### `auth.ts` -## requestMachine.ts +Sets up and enforces app‑level authentication. On first launch — after language selection and the intro sliders — the user chooses an unlock method (passcode or biometric). Reaching the Home screen marks the app **authorized**; logging out from Settings marks it **unauthorized**. -This state machine is instantiated when the user launches the verification section which displays the QR code. This QR is generated with content from a low-level [offline VC-sharing component](../components.md#offline-vc-sharing-component). The content of the QR code is scanned by a wallet Inji Wallet application to establish connection with verifier and share the VC credential. Once the VC is received on the Verifier side, the state machine allows seeing the received VC details as well for Verification. +#### `settings.ts` -## scanMachine.ts +Backs the Settings screen and its interactions: language switching, toggling biometric unlock, changing the credential‑registry / eSignet host, viewing received cards, etc. -This state machine is instantiated when the user launches the scanner section which opens up the camera to scan the QR code presented by the Verifier. The scanned data is fed into the underlying [offline VC sharing component](../components.md#offline-vc-sharing-component) to allow the discovery of the Verifier device and establish a connection to it. Once the connection is established, the user is allowed to select the downloaded VCs that can be shared with Verifier. The state machine also allows selfie/face verification before sharing VC. +#### `activityLog.ts` -## QrLoginMachine.ts +Maintains the audit trail shown on the History screen — VC downloaded, VC received, VC shared, and similar events. -This state machine facilitates flow for `Login with QR code` through Open ID connect from various portals. This is launched when the user opens up the scanner and scans a QR code from a website that supports login with Inji Wallet. Once the scan is performed, the user can review the required claims and select voluntary claims to be submitted. Once the submission is done successfully, the portal will be able to redirect automatically and logs the user in. +#### `biometrics.ts` -## pinInput.ts +Handles enabling/disabling biometric unlock from Settings and performing the biometric unlock itself. -This is a utility state machine which is used to facilitate PIN/OTP login wherever required in the application. +#### `pinInput.ts` -## faceSanner.ts +A small utility machine that drives PIN/OTP entry wherever it is needed in the app. -This is a state machine which facilitates the interactions to face scanning. It is used to support face authentication in Login with a QR code, sharing with selfies flow. +### Credential issuance — OpenID4VCI -## biometrics.ts +#### `Issuers/IssuersMachine.ts` -This state machine facilitates toggling biometric unlock on/off settings screen. This also allows setting up and using biometric unlock for the application. +Owns the **entire OpenID4VCI download journey**. It calls Mimoto's `/issuers` and `/issuers/{id}` endpoints to list issuers and cache their configuration, then, for the selected issuer, it: + +* performs OIDC authorization (authorization‑code and pre‑authorized/credential‑offer flows, including transaction‑code / `tx_code` prompts), +* generates the key pair and builds the proof JWT for the credential request, +* downloads the credential via the [VCI‑Client SDK](../integration-guide/vci-client.md), +* verifies the credential, and +* hands it to `vcMeta`/`store` to be persisted. + +It also handles **credential offers received via deep link** and reacts to network changes. This is the primary machine to extend when adding a new issuance capability. See also the [Credential Provider](credential_providers.md) customization. + +### Credential lifecycle + +#### `VerifiableCredential/VCMetaMachine` + +Manages the **metadata for all credentials** — the "My VCs" list on Home and the "Received VCs" list. It tracks download progress/success/failure and, for each stored credential, **spawns a `VCItemMachine`** to manage that credential individually. + +#### `VerifiableCredential/VCItemMachine` + +Spawned **once per credential**, this machine tracks a single VC's lifecycle: loading it from memory or from the server, fetching the issuer `.well-known`, verifying the credential, pinning/unpinning, activating for online login, showing QR/details, and deletion. Any new per‑credential feature belongs here. It is a `parallel` machine so utility state (load/refresh) and feature state can progress independently. + +### Online sharing — OpenID4VP + +#### `openID4VP/openID4VPMachine` + +Drives **online credential presentation** using OpenID4VP (via the [OpenID4VP SDK](../integration-guide/openid4vp.md)). It receives the authorization request (scanned or via deep link), lets the user select which VC(s) to present, optionally performs **face authentication** (share‑with‑selfie) through `faceScanner`, constructs and sends the Verifiable Presentation to the verifier, and logs the activity. + +### Offline sharing — BLE (Tuvali) + +Offline sharing uses the [Tuvali BLE SDK](../integration-guide/tuvali/) and the [BLE Verifier](../integration-guide/ble-verifier.md) integration. + +#### `bleShare/scan/scanMachine.ts` + +Instantiated when the user opens the **scanner** to share a credential. It scans the verifier's QR code, discovers and connects to the verifier device over BLE, lets the user pick which downloaded VC(s) to share, optionally runs selfie/face verification, and transmits the credential. + +#### `bleShare/request/requestMachine.ts` + +The receiving side (spawned on **Android only**). Instantiated when a device acts as a verifier: it displays the QR code, accepts the incoming BLE connection, receives the shared VC, and lets the user view/verify the received credential. + +### Login with QR — OpenID Connect + +#### `QrLogin/QrLoginMachine.ts` + +Powers **"Login with QR code"** on portals that support OpenID Connect with Inji Wallet. After scanning the login QR, the user reviews the mandatory claims and selects any voluntary claims, and on successful submission the portal logs the user in and redirects automatically. + +### Face authentication + +#### `faceScanner.ts` + +Encapsulates the face‑capture interaction. It is reused wherever face authentication is required — share‑with‑selfie (both online OpenID4VP and offline BLE flows). See the [Face Match integration](../integration-guide/face-match.md). + +### Backup & Restore + +Backup/restore protect the wallet's credentials to the user's own cloud (Google Drive on Android, iCloud on iOS). + +#### `backupAndRestore/backup` + +Handles backing up the encrypted credentials to cloud storage. + +#### `backupAndRestore/restore` + +Handles fetching, decrypting, and verifying the backed‑up credentials during restore. + +#### `backupAndRestore/backupAndRestoreSetup` + +Handles the one‑time setup/consent (cloud sign‑in, account selection) shared by both the backup and restore flows. + +## How to customize a workflow + +### 1. Change behaviour inside an existing flow + +Most customizations are one of these: + +* **Add or change a state / transition** — edit the state chart in the machine file (e.g. `IssuersMachine.ts`). Add the new `states:` node and the `on:` transitions that reach it. +* **Add an action** — add it to the corresponding `*Actions.ts` (or the `actions` block for single‑file machines) and reference it by name from the chart. +* **Add a condition** — add a guard to `*Guards.ts` and reference it via `cond:` on a transition. +* **Add async work** — add a service to `*Services.ts` and `invoke:` it from a state. +* **Expose new data to the UI** — add a selector in `*Selectors.ts`; screens read machine state through these selectors, not by reaching into context directly. + +### 2. Keep typegen in sync after editing + +XState v4 uses `tsTypes` files (`*.typegen.ts`) to give type‑safe `actions`, `guards`, and `services`. These files are generated for you — never edit them by hand. Inji Wallet relies on the [Stately / XState VS Code extension](https://marketplace.visualstudio.com/items?itemName=statelyai.stately-vscode), which regenerates the matching `*.typegen.ts` automatically whenever you save a machine that declares `tsTypes: {} as import('./X.typegen').Typegen0`. + +After adding or renaming an action, guard, or service, save the file (or run typegen via `@xstate/cli` if you have it installed) so TypeScript stays in sync. If a name in the chart has no counterpart in the generated types, the build will flag it. + +### 3. Add a brand‑new machine + +1. Create the folder/files following the [convention above](#anatomy-of-a-machine-the-file-convention) (`Model`, `Machine`, `Actions`, `Guards`, `Services`, `Selectors`). +2. Export a `createYourMachine(serviceRefs)` factory if the machine needs to talk to siblings. +3. If it should live for the whole session, `spawn` it in `app.ts` inside `spawnServiceActors` and add its ref to `AppServices` (`shared/GlobalContext`). Otherwise spawn it on demand from the parent flow that needs it. +4. Wire the screen to it via selectors and `send`. + +### 4. Visualize while you work + +Open a machine in the [XState Visualizer](https://stately.ai/viz) or the Stately VS Code extension to see the chart, simulate events, and validate that every state is reachable before you write tests. + +### 5. Test your changes + +Each machine ships with a co‑located `*.test.ts`. Model your new states/transitions the same way and run: + +```bash +npm test -- machines/ +``` + +## Related pages + +* [Architecture](../architecture.md) & [Components](../components.md) — where these machines sit in the wider app. +* [Configuration](configuration.md) — server‑driven properties consumed by these flows. +* [Credential Provider](credential_providers.md) — adding a new issuer to the OpenID4VCI flow. +* [Integration Guide](../integration-guide/) — the SDKs (VCI‑Client, OpenID4VP, Tuvali, Face Match, Secure Keystore) invoked by the machine `services`. From 2a3a98a67bd675ab514ba2137ab0c786c5dd259e Mon Sep 17 00:00:00 2001 From: abhip2565 Date: Tue, 7 Jul 2026 16:17:48 +0530 Subject: [PATCH 2/7] docs(inji-mobile): add flows-covered bullets to key machines Add a concise 'Flows covered' list (2-3 bullets) to the important machines - app, Issuers, VCMeta, VCItem, openID4VP, BLE scan/request, QrLogin, backup and restore - so consumers can see the concrete journeys each one drives at a glance. Signed-off-by: abhip2565 --- .../workflow-customization.md | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md b/inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md index de91035..c7ef1c5 100644 --- a/inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md +++ b/inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md @@ -90,6 +90,12 @@ The machines are grouped below by the capability they power. The **root** machine. On start it first spawns `store`, checks/generates cryptographic key pairs, fetches remote configuration (cache TTL and other properties via Mimoto's `allProperties` API), loads the credential‑registry and eSignet host from storage, and only then spawns the remaining service actors and moves to the `ready` (parallel) state. In `ready` it continuously tracks **app focus** and **network** status and broadcasts them to all children. It also handles deep links for QR login, OpenID4VP, and credential offers. +**Flows covered:** + +* Cold‑start boot sequence: storage → key pairs → config → service actors → `ready`. +* App lifecycle broadcasting (focus/blur, online/offline) to every child machine. +* Deep‑link routing for QR login, OpenID4VP requests, and credential offers. + #### `store.ts` The single gateway for all persistence. It exposes `GET`/`SET`/`APPEND`/`REMOVE`/`CLEAR` style events to the rest of the app and performs the **encryption/decryption** for data at rest. It abstracts the underlying storage engines: @@ -133,22 +139,46 @@ Owns the **entire OpenID4VCI download journey**. It calls Mimoto's `/issuers` an It also handles **credential offers received via deep link** and reacts to network changes. This is the primary machine to extend when adding a new issuance capability. See also the [Credential Provider](credential_providers.md) customization. +**Flows covered:** + +* Authorization‑code flow — user authenticates with the issuer/eSignet, then the credential is requested and downloaded. +* Pre‑authorized / credential‑offer flow — including `tx_code` (transaction code) prompts and consent screens. +* Credential offer opened via deep link, guarded so it is only accepted when the machine is in a safe state. + ### Credential lifecycle #### `VerifiableCredential/VCMetaMachine` Manages the **metadata for all credentials** — the "My VCs" list on Home and the "Received VCs" list. It tracks download progress/success/failure and, for each stored credential, **spawns a `VCItemMachine`** to manage that credential individually. +**Flows covered:** + +* Loading and maintaining the My VCs and Received VCs lists from `store`. +* Tracking in‑progress downloads and surfacing download success/failure banners. +* Spawning and tearing down a per‑credential `VCItemMachine` as VCs are added/removed. + #### `VerifiableCredential/VCItemMachine` Spawned **once per credential**, this machine tracks a single VC's lifecycle: loading it from memory or from the server, fetching the issuer `.well-known`, verifying the credential, pinning/unpinning, activating for online login, showing QR/details, and deletion. Any new per‑credential feature belongs here. It is a `parallel` machine so utility state (load/refresh) and feature state can progress independently. +**Flows covered:** + +* Load a VC from memory, or (re)download and store it from the issuer when missing. +* Verify the credential and refresh the issuer `.well-known` metadata. +* Per‑card actions — pin/unpin, view QR/details, and delete. + ### Online sharing — OpenID4VP #### `openID4VP/openID4VPMachine` Drives **online credential presentation** using OpenID4VP (via the [OpenID4VP SDK](../integration-guide/openid4vp.md)). It receives the authorization request (scanned or via deep link), lets the user select which VC(s) to present, optionally performs **face authentication** (share‑with‑selfie) through `faceScanner`, constructs and sends the Verifiable Presentation to the verifier, and logs the activity. +**Flows covered:** + +* Simple presentation — select VC(s) and share the Verifiable Presentation with the verifier. +* Share‑with‑selfie — the same flow gated behind a face‑authentication consent + capture step. +* Requests arriving from a full scan vs. the Home mini‑view vs. an OpenID4VP deep link. + ### Offline sharing — BLE (Tuvali) Offline sharing uses the [Tuvali BLE SDK](../integration-guide/tuvali/) and the [BLE Verifier](../integration-guide/ble-verifier.md) integration. @@ -157,16 +187,34 @@ Offline sharing uses the [Tuvali BLE SDK](../integration-guide/tuvali/) and the Instantiated when the user opens the **scanner** to share a credential. It scans the verifier's QR code, discovers and connects to the verifier device over BLE, lets the user pick which downloaded VC(s) to share, optionally runs selfie/face verification, and transmits the credential. +**Flows covered:** + +* Scan verifier QR → BLE device discovery → secure connection handshake. +* Select VC(s), optional selfie/face verification, then transmit over BLE. +* Connection/transfer error and retry handling (e.g. Bluetooth off, verifier out of range). + #### `bleShare/request/requestMachine.ts` The receiving side (spawned on **Android only**). Instantiated when a device acts as a verifier: it displays the QR code, accepts the incoming BLE connection, receives the shared VC, and lets the user view/verify the received credential. +**Flows covered:** + +* Generate and display the QR code that a wallet scans to initiate sharing. +* Accept the incoming BLE connection and receive the shared VC. +* Show and verify the received credential, then store it under Received VCs. + ### Login with QR — OpenID Connect #### `QrLogin/QrLoginMachine.ts` Powers **"Login with QR code"** on portals that support OpenID Connect with Inji Wallet. After scanning the login QR, the user reviews the mandatory claims and selects any voluntary claims, and on successful submission the portal logs the user in and redirects automatically. +**Flows covered:** + +* Scan a portal login QR and resolve the requested essential vs. voluntary claims. +* Consent capture — user confirms essential claims and opts into voluntary ones. +* Optional face‑verification consent before submitting, then automatic portal redirect on success. + ### Face authentication #### `faceScanner.ts` @@ -181,10 +229,20 @@ Backup/restore protect the wallet's credentials to the user's own cloud (Google Handles backing up the encrypted credentials to cloud storage. +**Flows covered:** + +* Trigger a backup (manual or automatic), package the encrypted VCs, and upload to the user's cloud. +* Report progress and last‑backup status back to the Settings screen. + #### `backupAndRestore/restore` Handles fetching, decrypting, and verifying the backed‑up credentials during restore. +**Flows covered:** + +* Locate and download the latest backup from the user's cloud. +* Decrypt, verify, and re‑import the credentials into local storage. + #### `backupAndRestore/backupAndRestoreSetup` Handles the one‑time setup/consent (cloud sign‑in, account selection) shared by both the backup and restore flows. From 958c719bccc7d23d53058bf3853ccf6e88244340 Mon Sep 17 00:00:00 2001 From: abhip2565 Date: Tue, 7 Jul 2026 16:20:29 +0530 Subject: [PATCH 3/7] docs(inji-mobile): fix non-breaking hyphens and fragile anchor Replace U+2011 non-breaking hyphens with plain ASCII hyphens for on-site search/copy consistency, and point the typegen note at a stable section heading anchor instead of a numbered-heading anchor that GitBook may slug unpredictably. Signed-off-by: abhip2565 --- .../workflow-customization.md | 80 +++++++++---------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md b/inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md index c7ef1c5..61aed30 100644 --- a/inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md +++ b/inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md @@ -2,11 +2,11 @@ ## Overview -Every user journey in **Inji Wallet** (release **1.x**) — onboarding, downloading a credential, sharing it online or offline, backing it up, logging in with a QR code — is modelled as a **finite‑state machine (FSM)**. Modelling flows as state machines keeps the behaviour explicit and predictable: at any point in time the app is in exactly one well‑defined state, and it can only move to another state in response to a known event. +Every user journey in **Inji Wallet** (release **1.x**) — onboarding, downloading a credential, sharing it online or offline, backing it up, logging in with a QR code — is modelled as a **finite-state machine (FSM)**. Modelling flows as state machines keeps the behaviour explicit and predictable: at any point in time the app is in exactly one well-defined state, and it can only move to another state in response to a known event. -The state machines are written with [**XState v4**](https://xstate.js.org/docs/) (`xstate@^4.35.0`) and live in the [`machines/`](https://github.com/mosip/inji-wallet/tree/master/machines) folder of the Inji Wallet codebase. A few very screen‑specific machines live under `screens/`, but the reusable, customizable workflow logic is concentrated in `machines/`. +The state machines are written with [**XState v4**](https://xstate.js.org/docs/) (`xstate@^4.35.0`) and live in the [`machines/`](https://github.com/mosip/inji-wallet/tree/master/machines) folder of the Inji Wallet codebase. A few very screen-specific machines live under `screens/`, but the reusable, customizable workflow logic is concentrated in `machines/`. -Implementers can reuse the existing machines as‑is, extend them (add states, actions, guards, or services), or replace a whole flow with their own machine — this page explains how the machines are structured and wired together so you can do that confidently. +Implementers can reuse the existing machines as-is, extend them (add states, actions, guards, or services), or replace a whole flow with their own machine — this page explains how the machines are structured and wired together so you can do that confidently. {% hint style="info" %} XState is a data structure + interpreter. Editing a machine is mostly editing a plain JavaScript object (the state chart) plus its associated `actions`, `guards`, and `services`. You rarely need to touch the React screens to change a workflow — you change the machine that drives them. @@ -14,7 +14,7 @@ XState is a data structure + interpreter. Editing a machine is mostly editing a ## How the machines are wired together -Inji Wallet uses a **multi‑actor** architecture. A root machine boots the app and **spawns** long‑lived child machines ("service actors"). These references are kept in a shared context object (`AppServices`, exposed through `shared/GlobalContext`) so any part of the app can `send` events to any machine. +Inji Wallet uses a **multi-actor** architecture. A root machine boots the app and **spawns** long-lived child machines ("service actors"). These references are kept in a shared context object (`AppServices`, exposed through `shared/GlobalContext`) so any part of the app can `send` events to any machine. ``` app.ts (root) @@ -40,7 +40,7 @@ Machines that are spawned **on demand** (not at boot) include: * `QrLoginMachine` — "Login with QR code" (OpenID Connect), spawned from the scanner. * `faceScanner`, `pinInput`, `biometrics` — utility machines used inside other flows. -### The factory‑and‑spawn pattern +### The factory-and-spawn pattern Every service machine exports a **factory function** `createXMachine(serviceRefs)` alongside the machine instance. `app.ts` calls the factory with the current `serviceRefs` and `spawn`s it, so the child machine can reach its siblings: @@ -56,7 +56,7 @@ serviceRefs.vcMeta = spawn( * **Parent → child:** `send(EVENT, { to: context.serviceRefs. })`. * **Child → parent:** `sendParent(EVENT)`. -* **App‑wide broadcasts:** `app.ts` forwards lifecycle changes (focus/blur, online/offline) to every service actor by re‑emitting the event with an `APP_` prefix (see the `forwardToServices` action). So a child machine can react to `APP_ONLINE`, `APP_OFFLINE`, `APP_ACTIVE`, etc. +* **App-wide broadcasts:** `app.ts` forwards lifecycle changes (focus/blur, online/offline) to every service actor by re-emitting the event with an `APP_` prefix (see the `forwardToServices` action). So a child machine can react to `APP_ONLINE`, `APP_OFFLINE`, `APP_ACTIVE`, etc. * **Storage:** no machine touches the disk directly. They all send `StoreEvents.GET/SET/…` to the `store` actor, which centralises encryption/decryption and persistence. ## Anatomy of a machine (the file convention) @@ -65,19 +65,19 @@ Simple machines are a single file (e.g. `auth.ts`, `settings.ts`). The larger fl | File | Responsibility | | --- | --- | -| `IssuersModel.ts` | Declares the machine **context** (data) and the **events** it accepts, using `createModel(...)`. This is the type‑safe contract for the machine. | +| `IssuersModel.ts` | Declares the machine **context** (data) and the **events** it accepts, using `createModel(...)`. This is the type-safe contract for the machine. | | `IssuersMachine.ts` | The **state chart** — states, transitions, `initial` state, invoked services. Wires in the actions/guards/services below. | -| `IssuersActions.ts` | Pure `assign`/side‑effect **actions** that mutate context or fire effects. | +| `IssuersActions.ts` | Pure `assign`/side-effect **actions** that mutate context or fire effects. | | `IssuersGuards.ts` | **Guard** (condition) functions used in `cond:` to choose between transitions. | | `IssuersService.ts` | **Services** — the async work (API calls, crypto, SDK calls) invoked by states. | | `IssuersSelectors.ts` | **Selectors** — read helpers that components use to derive UI state from the machine. | | `IssuersEvents.ts` | Shared event creators (when events are reused across files). | -| `*.typegen.ts` | **Auto‑generated** type‑safety helpers for XState. Do not edit by hand (see [Keep typegen in sync](#2-keep-typegen-in-sync-after-editing)). | +| `*.typegen.ts` | **Auto-generated** type-safety helpers for XState. Do not edit by hand — they are regenerated for you (see _Keep typegen in sync_ under [How to customize a workflow](#how-to-customize-a-workflow)). | -The single‑file machines (`auth.ts`, `store.ts`, `settings.ts`, …) keep the same building blocks (`model`, `states`, `actions`, `guards`, `services`) inline within one file. +The single-file machines (`auth.ts`, `store.ts`, `settings.ts`, …) keep the same building blocks (`model`, `states`, `actions`, `guards`, `services`) inline within one file. {% hint style="info" %} -Many machine files begin with an `@xstate-layout` comment. That hash is used by the [Stately](https://stately.ai/) / [XState VS Code](https://marketplace.visualstudio.com/items?itemName=statelyai.stately-vscode) visual editor to render and round‑trip the chart. You can paste a machine into the [XState Visualizer](https://stately.ai/viz) to see and edit the flow graphically. +Many machine files begin with an `@xstate-layout` comment. That hash is used by the [Stately](https://stately.ai/) / [XState VS Code](https://marketplace.visualstudio.com/items?itemName=statelyai.stately-vscode) visual editor to render and round-trip the chart. You can paste a machine into the [XState Visualizer](https://stately.ai/viz) to see and edit the flow graphically. {% endhint %} ## Machine reference @@ -88,13 +88,13 @@ The machines are grouped below by the capability they power. #### `app.ts` -The **root** machine. On start it first spawns `store`, checks/generates cryptographic key pairs, fetches remote configuration (cache TTL and other properties via Mimoto's `allProperties` API), loads the credential‑registry and eSignet host from storage, and only then spawns the remaining service actors and moves to the `ready` (parallel) state. In `ready` it continuously tracks **app focus** and **network** status and broadcasts them to all children. It also handles deep links for QR login, OpenID4VP, and credential offers. +The **root** machine. On start it first spawns `store`, checks/generates cryptographic key pairs, fetches remote configuration (cache TTL and other properties via Mimoto's `allProperties` API), loads the credential-registry and eSignet host from storage, and only then spawns the remaining service actors and moves to the `ready` (parallel) state. In `ready` it continuously tracks **app focus** and **network** status and broadcasts them to all children. It also handles deep links for QR login, OpenID4VP, and credential offers. **Flows covered:** -* Cold‑start boot sequence: storage → key pairs → config → service actors → `ready`. +* Cold-start boot sequence: storage → key pairs → config → service actors → `ready`. * App lifecycle broadcasting (focus/blur, online/offline) to every child machine. -* Deep‑link routing for QR login, OpenID4VP requests, and credential offers. +* Deep-link routing for QR login, OpenID4VP requests, and credential offers. #### `store.ts` @@ -103,15 +103,15 @@ The single gateway for all persistence. It exposes `GET`/`SET`/`APPEND`/`REMOVE` * [`react-native-mmkv-storage`](https://github.com/ammarahm-ed/react-native-mmkv-storage) — stores metadata and references to encrypted VCs. * [`react-native-fs`](https://www.npmjs.com/package/react-native-fs) — stores each encrypted VC as a separate file. -Key material is held in the hardware‑backed keystore (see [Secure Keystore](../integration-guide/secure-keystore.md)). +Key material is held in the hardware-backed keystore (see [Secure Keystore](../integration-guide/secure-keystore.md)). #### `auth.ts` -Sets up and enforces app‑level authentication. On first launch — after language selection and the intro sliders — the user chooses an unlock method (passcode or biometric). Reaching the Home screen marks the app **authorized**; logging out from Settings marks it **unauthorized**. +Sets up and enforces app-level authentication. On first launch — after language selection and the intro sliders — the user chooses an unlock method (passcode or biometric). Reaching the Home screen marks the app **authorized**; logging out from Settings marks it **unauthorized**. #### `settings.ts` -Backs the Settings screen and its interactions: language switching, toggling biometric unlock, changing the credential‑registry / eSignet host, viewing received cards, etc. +Backs the Settings screen and its interactions: language switching, toggling biometric unlock, changing the credential-registry / eSignet host, viewing received cards, etc. #### `activityLog.ts` @@ -131,9 +131,9 @@ A small utility machine that drives PIN/OTP entry wherever it is needed in the a Owns the **entire OpenID4VCI download journey**. It calls Mimoto's `/issuers` and `/issuers/{id}` endpoints to list issuers and cache their configuration, then, for the selected issuer, it: -* performs OIDC authorization (authorization‑code and pre‑authorized/credential‑offer flows, including transaction‑code / `tx_code` prompts), +* performs OIDC authorization (authorization-code and pre-authorized/credential-offer flows, including transaction-code / `tx_code` prompts), * generates the key pair and builds the proof JWT for the credential request, -* downloads the credential via the [VCI‑Client SDK](../integration-guide/vci-client.md), +* downloads the credential via the [VCI-Client SDK](../integration-guide/vci-client.md), * verifies the credential, and * hands it to `vcMeta`/`store` to be persisted. @@ -141,8 +141,8 @@ It also handles **credential offers received via deep link** and reacts to netwo **Flows covered:** -* Authorization‑code flow — user authenticates with the issuer/eSignet, then the credential is requested and downloaded. -* Pre‑authorized / credential‑offer flow — including `tx_code` (transaction code) prompts and consent screens. +* Authorization-code flow — user authenticates with the issuer/eSignet, then the credential is requested and downloaded. +* Pre-authorized / credential-offer flow — including `tx_code` (transaction code) prompts and consent screens. * Credential offer opened via deep link, guarded so it is only accepted when the machine is in a safe state. ### Credential lifecycle @@ -154,30 +154,30 @@ Manages the **metadata for all credentials** — the "My VCs" list on Home and t **Flows covered:** * Loading and maintaining the My VCs and Received VCs lists from `store`. -* Tracking in‑progress downloads and surfacing download success/failure banners. -* Spawning and tearing down a per‑credential `VCItemMachine` as VCs are added/removed. +* Tracking in-progress downloads and surfacing download success/failure banners. +* Spawning and tearing down a per-credential `VCItemMachine` as VCs are added/removed. #### `VerifiableCredential/VCItemMachine` -Spawned **once per credential**, this machine tracks a single VC's lifecycle: loading it from memory or from the server, fetching the issuer `.well-known`, verifying the credential, pinning/unpinning, activating for online login, showing QR/details, and deletion. Any new per‑credential feature belongs here. It is a `parallel` machine so utility state (load/refresh) and feature state can progress independently. +Spawned **once per credential**, this machine tracks a single VC's lifecycle: loading it from memory or from the server, fetching the issuer `.well-known`, verifying the credential, pinning/unpinning, activating for online login, showing QR/details, and deletion. Any new per-credential feature belongs here. It is a `parallel` machine so utility state (load/refresh) and feature state can progress independently. **Flows covered:** * Load a VC from memory, or (re)download and store it from the issuer when missing. * Verify the credential and refresh the issuer `.well-known` metadata. -* Per‑card actions — pin/unpin, view QR/details, and delete. +* Per-card actions — pin/unpin, view QR/details, and delete. ### Online sharing — OpenID4VP #### `openID4VP/openID4VPMachine` -Drives **online credential presentation** using OpenID4VP (via the [OpenID4VP SDK](../integration-guide/openid4vp.md)). It receives the authorization request (scanned or via deep link), lets the user select which VC(s) to present, optionally performs **face authentication** (share‑with‑selfie) through `faceScanner`, constructs and sends the Verifiable Presentation to the verifier, and logs the activity. +Drives **online credential presentation** using OpenID4VP (via the [OpenID4VP SDK](../integration-guide/openid4vp.md)). It receives the authorization request (scanned or via deep link), lets the user select which VC(s) to present, optionally performs **face authentication** (share-with-selfie) through `faceScanner`, constructs and sends the Verifiable Presentation to the verifier, and logs the activity. **Flows covered:** * Simple presentation — select VC(s) and share the Verifiable Presentation with the verifier. -* Share‑with‑selfie — the same flow gated behind a face‑authentication consent + capture step. -* Requests arriving from a full scan vs. the Home mini‑view vs. an OpenID4VP deep link. +* Share-with-selfie — the same flow gated behind a face-authentication consent + capture step. +* Requests arriving from a full scan vs. the Home mini-view vs. an OpenID4VP deep link. ### Offline sharing — BLE (Tuvali) @@ -213,13 +213,13 @@ Powers **"Login with QR code"** on portals that support OpenID Connect with Inji * Scan a portal login QR and resolve the requested essential vs. voluntary claims. * Consent capture — user confirms essential claims and opts into voluntary ones. -* Optional face‑verification consent before submitting, then automatic portal redirect on success. +* Optional face-verification consent before submitting, then automatic portal redirect on success. ### Face authentication #### `faceScanner.ts` -Encapsulates the face‑capture interaction. It is reused wherever face authentication is required — share‑with‑selfie (both online OpenID4VP and offline BLE flows). See the [Face Match integration](../integration-guide/face-match.md). +Encapsulates the face-capture interaction. It is reused wherever face authentication is required — share-with-selfie (both online OpenID4VP and offline BLE flows). See the [Face Match integration](../integration-guide/face-match.md). ### Backup & Restore @@ -232,20 +232,20 @@ Handles backing up the encrypted credentials to cloud storage. **Flows covered:** * Trigger a backup (manual or automatic), package the encrypted VCs, and upload to the user's cloud. -* Report progress and last‑backup status back to the Settings screen. +* Report progress and last-backup status back to the Settings screen. #### `backupAndRestore/restore` -Handles fetching, decrypting, and verifying the backed‑up credentials during restore. +Handles fetching, decrypting, and verifying the backed-up credentials during restore. **Flows covered:** * Locate and download the latest backup from the user's cloud. -* Decrypt, verify, and re‑import the credentials into local storage. +* Decrypt, verify, and re-import the credentials into local storage. #### `backupAndRestore/backupAndRestoreSetup` -Handles the one‑time setup/consent (cloud sign‑in, account selection) shared by both the backup and restore flows. +Handles the one-time setup/consent (cloud sign-in, account selection) shared by both the backup and restore flows. ## How to customize a workflow @@ -254,18 +254,18 @@ Handles the one‑time setup/consent (cloud sign‑in, account selection) shared Most customizations are one of these: * **Add or change a state / transition** — edit the state chart in the machine file (e.g. `IssuersMachine.ts`). Add the new `states:` node and the `on:` transitions that reach it. -* **Add an action** — add it to the corresponding `*Actions.ts` (or the `actions` block for single‑file machines) and reference it by name from the chart. +* **Add an action** — add it to the corresponding `*Actions.ts` (or the `actions` block for single-file machines) and reference it by name from the chart. * **Add a condition** — add a guard to `*Guards.ts` and reference it via `cond:` on a transition. * **Add async work** — add a service to `*Services.ts` and `invoke:` it from a state. * **Expose new data to the UI** — add a selector in `*Selectors.ts`; screens read machine state through these selectors, not by reaching into context directly. ### 2. Keep typegen in sync after editing -XState v4 uses `tsTypes` files (`*.typegen.ts`) to give type‑safe `actions`, `guards`, and `services`. These files are generated for you — never edit them by hand. Inji Wallet relies on the [Stately / XState VS Code extension](https://marketplace.visualstudio.com/items?itemName=statelyai.stately-vscode), which regenerates the matching `*.typegen.ts` automatically whenever you save a machine that declares `tsTypes: {} as import('./X.typegen').Typegen0`. +XState v4 uses `tsTypes` files (`*.typegen.ts`) to give type-safe `actions`, `guards`, and `services`. These files are generated for you — never edit them by hand. Inji Wallet relies on the [Stately / XState VS Code extension](https://marketplace.visualstudio.com/items?itemName=statelyai.stately-vscode), which regenerates the matching `*.typegen.ts` automatically whenever you save a machine that declares `tsTypes: {} as import('./X.typegen').Typegen0`. After adding or renaming an action, guard, or service, save the file (or run typegen via `@xstate/cli` if you have it installed) so TypeScript stays in sync. If a name in the chart has no counterpart in the generated types, the build will flag it. -### 3. Add a brand‑new machine +### 3. Add a brand-new machine 1. Create the folder/files following the [convention above](#anatomy-of-a-machine-the-file-convention) (`Model`, `Machine`, `Actions`, `Guards`, `Services`, `Selectors`). 2. Export a `createYourMachine(serviceRefs)` factory if the machine needs to talk to siblings. @@ -278,7 +278,7 @@ Open a machine in the [XState Visualizer](https://stately.ai/viz) or the Stately ### 5. Test your changes -Each machine ships with a co‑located `*.test.ts`. Model your new states/transitions the same way and run: +Each machine ships with a co-located `*.test.ts`. Model your new states/transitions the same way and run: ```bash npm test -- machines/ @@ -287,6 +287,6 @@ npm test -- machines/ ## Related pages * [Architecture](../architecture.md) & [Components](../components.md) — where these machines sit in the wider app. -* [Configuration](configuration.md) — server‑driven properties consumed by these flows. +* [Configuration](configuration.md) — server-driven properties consumed by these flows. * [Credential Provider](credential_providers.md) — adding a new issuer to the OpenID4VCI flow. -* [Integration Guide](../integration-guide/) — the SDKs (VCI‑Client, OpenID4VP, Tuvali, Face Match, Secure Keystore) invoked by the machine `services`. +* [Integration Guide](../integration-guide/) — the SDKs (VCI-Client, OpenID4VP, Tuvali, Face Match, Secure Keystore) invoked by the machine `services`. From 69be23cdb347342c822395903a611eb94a0d5874 Mon Sep 17 00:00:00 2001 From: abhip2565 Date: Tue, 7 Jul 2026 16:56:17 +0530 Subject: [PATCH 4/7] docs(inji-mobile): fix machine heading hierarchy and drop code-style headers Promote capability groups to H2 and machine names to plain-text H3 (previously H4 wrapped in inline code, which rendered smaller than the bold 'Flows covered' labels beneath them). Machine headers are now plain text, consistent with the rest of the docs. Signed-off-by: abhip2565 --- .../workflow-customization.md | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md b/inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md index 61aed30..0aa6c5e 100644 --- a/inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md +++ b/inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md @@ -82,11 +82,11 @@ Many machine files begin with an `@xstate-layout` comment. That hash is used by ## Machine reference -The machines are grouped below by the capability they power. +The machines are grouped below by the capability they power. Each entry describes what the machine is responsible for and the concrete flows it drives. -### Bootstrap & core +## Bootstrap & core -#### `app.ts` +### app.ts The **root** machine. On start it first spawns `store`, checks/generates cryptographic key pairs, fetches remote configuration (cache TTL and other properties via Mimoto's `allProperties` API), loads the credential-registry and eSignet host from storage, and only then spawns the remaining service actors and moves to the `ready` (parallel) state. In `ready` it continuously tracks **app focus** and **network** status and broadcasts them to all children. It also handles deep links for QR login, OpenID4VP, and credential offers. @@ -96,7 +96,7 @@ The **root** machine. On start it first spawns `store`, checks/generates cryptog * App lifecycle broadcasting (focus/blur, online/offline) to every child machine. * Deep-link routing for QR login, OpenID4VP requests, and credential offers. -#### `store.ts` +### store.ts The single gateway for all persistence. It exposes `GET`/`SET`/`APPEND`/`REMOVE`/`CLEAR` style events to the rest of the app and performs the **encryption/decryption** for data at rest. It abstracts the underlying storage engines: @@ -105,29 +105,29 @@ The single gateway for all persistence. It exposes `GET`/`SET`/`APPEND`/`REMOVE` Key material is held in the hardware-backed keystore (see [Secure Keystore](../integration-guide/secure-keystore.md)). -#### `auth.ts` +### auth.ts Sets up and enforces app-level authentication. On first launch — after language selection and the intro sliders — the user chooses an unlock method (passcode or biometric). Reaching the Home screen marks the app **authorized**; logging out from Settings marks it **unauthorized**. -#### `settings.ts` +### settings.ts Backs the Settings screen and its interactions: language switching, toggling biometric unlock, changing the credential-registry / eSignet host, viewing received cards, etc. -#### `activityLog.ts` +### activityLog.ts Maintains the audit trail shown on the History screen — VC downloaded, VC received, VC shared, and similar events. -#### `biometrics.ts` +### biometrics.ts Handles enabling/disabling biometric unlock from Settings and performing the biometric unlock itself. -#### `pinInput.ts` +### pinInput.ts A small utility machine that drives PIN/OTP entry wherever it is needed in the app. -### Credential issuance — OpenID4VCI +## Credential issuance — OpenID4VCI -#### `Issuers/IssuersMachine.ts` +### Issuers/IssuersMachine.ts Owns the **entire OpenID4VCI download journey**. It calls Mimoto's `/issuers` and `/issuers/{id}` endpoints to list issuers and cache their configuration, then, for the selected issuer, it: @@ -145,9 +145,9 @@ It also handles **credential offers received via deep link** and reacts to netwo * Pre-authorized / credential-offer flow — including `tx_code` (transaction code) prompts and consent screens. * Credential offer opened via deep link, guarded so it is only accepted when the machine is in a safe state. -### Credential lifecycle +## Credential lifecycle -#### `VerifiableCredential/VCMetaMachine` +### VerifiableCredential/VCMetaMachine Manages the **metadata for all credentials** — the "My VCs" list on Home and the "Received VCs" list. It tracks download progress/success/failure and, for each stored credential, **spawns a `VCItemMachine`** to manage that credential individually. @@ -157,7 +157,7 @@ Manages the **metadata for all credentials** — the "My VCs" list on Home and t * Tracking in-progress downloads and surfacing download success/failure banners. * Spawning and tearing down a per-credential `VCItemMachine` as VCs are added/removed. -#### `VerifiableCredential/VCItemMachine` +### VerifiableCredential/VCItemMachine Spawned **once per credential**, this machine tracks a single VC's lifecycle: loading it from memory or from the server, fetching the issuer `.well-known`, verifying the credential, pinning/unpinning, activating for online login, showing QR/details, and deletion. Any new per-credential feature belongs here. It is a `parallel` machine so utility state (load/refresh) and feature state can progress independently. @@ -167,9 +167,9 @@ Spawned **once per credential**, this machine tracks a single VC's lifecycle: lo * Verify the credential and refresh the issuer `.well-known` metadata. * Per-card actions — pin/unpin, view QR/details, and delete. -### Online sharing — OpenID4VP +## Online sharing — OpenID4VP -#### `openID4VP/openID4VPMachine` +### openID4VP/openID4VPMachine Drives **online credential presentation** using OpenID4VP (via the [OpenID4VP SDK](../integration-guide/openid4vp.md)). It receives the authorization request (scanned or via deep link), lets the user select which VC(s) to present, optionally performs **face authentication** (share-with-selfie) through `faceScanner`, constructs and sends the Verifiable Presentation to the verifier, and logs the activity. @@ -179,11 +179,11 @@ Drives **online credential presentation** using OpenID4VP (via the [OpenID4VP SD * Share-with-selfie — the same flow gated behind a face-authentication consent + capture step. * Requests arriving from a full scan vs. the Home mini-view vs. an OpenID4VP deep link. -### Offline sharing — BLE (Tuvali) +## Offline sharing — BLE (Tuvali) Offline sharing uses the [Tuvali BLE SDK](../integration-guide/tuvali/) and the [BLE Verifier](../integration-guide/ble-verifier.md) integration. -#### `bleShare/scan/scanMachine.ts` +### bleShare/scan/scanMachine.ts Instantiated when the user opens the **scanner** to share a credential. It scans the verifier's QR code, discovers and connects to the verifier device over BLE, lets the user pick which downloaded VC(s) to share, optionally runs selfie/face verification, and transmits the credential. @@ -193,7 +193,7 @@ Instantiated when the user opens the **scanner** to share a credential. It scans * Select VC(s), optional selfie/face verification, then transmit over BLE. * Connection/transfer error and retry handling (e.g. Bluetooth off, verifier out of range). -#### `bleShare/request/requestMachine.ts` +### bleShare/request/requestMachine.ts The receiving side (spawned on **Android only**). Instantiated when a device acts as a verifier: it displays the QR code, accepts the incoming BLE connection, receives the shared VC, and lets the user view/verify the received credential. @@ -203,9 +203,9 @@ The receiving side (spawned on **Android only**). Instantiated when a device act * Accept the incoming BLE connection and receive the shared VC. * Show and verify the received credential, then store it under Received VCs. -### Login with QR — OpenID Connect +## Login with QR — OpenID Connect -#### `QrLogin/QrLoginMachine.ts` +### QrLogin/QrLoginMachine.ts Powers **"Login with QR code"** on portals that support OpenID Connect with Inji Wallet. After scanning the login QR, the user reviews the mandatory claims and selects any voluntary claims, and on successful submission the portal logs the user in and redirects automatically. @@ -215,17 +215,17 @@ Powers **"Login with QR code"** on portals that support OpenID Connect with Inji * Consent capture — user confirms essential claims and opts into voluntary ones. * Optional face-verification consent before submitting, then automatic portal redirect on success. -### Face authentication +## Face authentication -#### `faceScanner.ts` +### faceScanner.ts Encapsulates the face-capture interaction. It is reused wherever face authentication is required — share-with-selfie (both online OpenID4VP and offline BLE flows). See the [Face Match integration](../integration-guide/face-match.md). -### Backup & Restore +## Backup & Restore Backup/restore protect the wallet's credentials to the user's own cloud (Google Drive on Android, iCloud on iOS). -#### `backupAndRestore/backup` +### backupAndRestore/backup Handles backing up the encrypted credentials to cloud storage. @@ -234,7 +234,7 @@ Handles backing up the encrypted credentials to cloud storage. * Trigger a backup (manual or automatic), package the encrypted VCs, and upload to the user's cloud. * Report progress and last-backup status back to the Settings screen. -#### `backupAndRestore/restore` +### backupAndRestore/restore Handles fetching, decrypting, and verifying the backed-up credentials during restore. @@ -243,7 +243,7 @@ Handles fetching, decrypting, and verifying the backed-up credentials during res * Locate and download the latest backup from the user's cloud. * Decrypt, verify, and re-import the credentials into local storage. -#### `backupAndRestore/backupAndRestoreSetup` +### backupAndRestore/backupAndRestoreSetup Handles the one-time setup/consent (cloud sign-in, account selection) shared by both the backup and restore flows. From 8b8fb55f8638277356951d5188316036f5977da7 Mon Sep 17 00:00:00 2001 From: abhip2565 Date: Wed, 8 Jul 2026 15:03:43 +0530 Subject: [PATCH 5/7] docs(inji-mobile): refresh customization docs for 1.x Signed-off-by: abhip2565 --- .../customization-overview/README.md | 12 +- .../customization-overview/configuration.md | 71 ++++- .../credential_providers.md | 260 ++++++++++-------- .../locale-customization.md | 73 ++++- .../ui-customization.md | 255 ++++++----------- .../workflow-customization.md | 2 +- 6 files changed, 366 insertions(+), 307 deletions(-) diff --git a/inji-wallet/inji-mobile/technical-overview/customization-overview/README.md b/inji-wallet/inji-mobile/technical-overview/customization-overview/README.md index bc9b878..59468f4 100644 --- a/inji-wallet/inji-mobile/technical-overview/customization-overview/README.md +++ b/inji-wallet/inji-mobile/technical-overview/customization-overview/README.md @@ -1,11 +1,11 @@ # Customizations -Countries also have the option to customize Inji as per their requirements. Refer to the documents below for more information on the same. +Implementers can customize Inji Wallet Mobile for their deployment, issuer set, supported languages, and branding. The pages in this section describe the extension points that are still current for the release 1.x mobile codebase. The following customizations are available in Inji: -* [Workflow Customization](https://docs.mosip.io/inji/customization-overview/workflow-customization) -* [UI Customization](https://docs.mosip.io/inji/customization-overview/ui-customization) -* [Locale Customization](https://docs.mosip.io/inji/customization-overview/locale-customization) -* [Configuration](https://docs.mosip.io/inji/customization-overview/configuration) -* [Credential Provider](https://docs.mosip.io/inji/customization-overview/credential_providers) +* [Workflow Customization](workflow-customization.md) +* [UI Customization](ui-customization.md) +* [Locale Customization](locale-customization.md) +* [Configuration](configuration.md) +* [Credential Provider](credential_providers.md) diff --git a/inji-wallet/inji-mobile/technical-overview/customization-overview/configuration.md b/inji-wallet/inji-mobile/technical-overview/customization-overview/configuration.md index f0c7fb6..2ab399c 100644 --- a/inji-wallet/inji-mobile/technical-overview/customization-overview/configuration.md +++ b/inji-wallet/inji-mobile/technical-overview/customization-overview/configuration.md @@ -2,23 +2,66 @@ ## Configuration for Inji Wallet -The configurable properties for Inji Wallet can be found at [inji-default.properties](https://github.com/mosip/inji-config/blob/master/inji-default.properties). This property file is maintained as one for each deployment environment. On [this](https://github.com/mosip/inji-config) repository, each environment configuration is placed in a corresponding branch specific to that environment. +The configurable properties for Inji Wallet Mobile are maintained in [`inji/inji-config`](https://github.com/inji/inji-config), primarily in [`inji-default.properties`](https://github.com/inji/inji-config/blob/master/inji-default.properties). Deployment environments can override these values through their config branch or deployment-specific property source. -> Refer to [inji-default.properties](https://github.com/mosip/inji-config/blob/collab/inji-default.properties) of Collab environment. +Mimoto loads these `mosip.inji.*` properties and exposes them to the wallet through: -These values will be used by Inji Wallet via Mimoto. Mimoto loads all the configurations and exposes an API which is used by the Inji Wallet application to fetch and store the configurations in the local storage. +```http +GET /v1/mimoto/allProperties +``` -API used to fetch these configurations: `https://api.collab.mosip.net/v1/mimoto/allProperties` +For example, in a deployment whose Mimoto base URL is `https://api.collab.mosip.net`, the wallet calls: -The implementers can choose to use the existing configurations or add new configurations to them. +```text +https://api.collab.mosip.net/v1/mimoto/allProperties +``` -The properties used by Inji Wallet are: +The wallet caches the response locally and falls back to `shared/InitialConfig.ts` on first launch if the API is unavailable. -* `mosip.inji.faceSdkModelUrl(https://${mosip.api.public.host}/inji)`: This is the path of the file server from where the face SDK model can be downloaded. -* `mosip.inji.modelDownloadMaxRetry(10)`: The maximum times the application will try to fetch the model. -* `mosip.inji.audience(ida-binding)`: This is used to generate the JWT token which will be passed during online login. -* `mosip.inji.issuer(residentapp)`: This is used to generate the JWT token which will be passed during online login. -* `mosip.inji.warningDomainName(https://${mosip.api.public.host})`: This is the mimoto domain used to access all Apis. -* `mosip.inji.aboutInjiUrl(https://docs.inji.io/inji-wallet/inji-mobile)`: This is the url for Inji Wallet Mobile documentation used in About Inji Wallet page. -* `mosip.inji.minStorageRequiredForAuditEntry(2)`: This is threshold(minimum storage space required) in MB for storing audit entries. -* `mosip.inji.minStorageRequired(2)`: This is threshold(minimum storage space required) in MB for storing downloaded / received vc. +## Properties Used by Mobile + +| Property | Default | Purpose | +| --- | --- | --- | +| `mosip.inji.allowedAuthType` | `demo,otp,bio-Finger,bio-Iris,bio-Face` | Allowed auth types for IDA-based flows. | +| `mosip.inji.allowedEkycAuthType` | `demo,otp,bio-Finger,bio-Iris,bio-Face` | Allowed eKYC auth types. | +| `mosip.inji.allowedInternalAuthType` | `otp,bio-Finger,bio-Iris,bio-Face` | Allowed internal auth types. | +| `mosip.inji.faceSdkModelUrl` | `https://${mosip.api.public.host}/inji` | Base path for downloading face SDK model assets. | +| `mosip.inji.modelDownloadMaxRetry` | `10` | Maximum retry count for face model download. | +| `mosip.inji.vcDownloadMaxRetry` | `10` | Maximum retry count while polling/downloading credentials. | +| `mosip.inji.vcDownloadPoolInterval` | `6000` | Poll interval, in milliseconds, for VC download status checks. | +| `mosip.inji.audience` | `ida-binding` | Audience value used in wallet binding/token flows. | +| `mosip.inji.issuer` | `residentapp` | Issuer value used in wallet binding/token flows. | +| `mosip.inji.warningDomainName` | `https://${mosip.api.public.host}` | Domain shown/used by warning screens and request handling. | +| `mosip.inji.openId4VCIDownloadVCTimeout` | `30000` | Timeout, in milliseconds, for OpenID4VCI credential download calls. | +| `mosip.inji.aboutInjiUrl` | Environment-specific docs URL | URL opened from the About Inji Wallet screen. | +| `mosip.inji.minStorageRequiredForAuditEntry` | `2` | Minimum free storage, in MB, before audit entries are written. | +| `mosip.inji.minStorageRequired` | `2` | Minimum free storage, in MB, before downloaded or received VCs are stored. | +| `mosip.inji.openid4vpClientValidation` | `true` | Enables pre-registered verifier validation in OpenID4VP sharing. | + +## Related Mimoto Configuration + +Several wallet behaviors are configured in [`mimoto-default.properties`](https://github.com/inji/inji-config/blob/master/mimoto-default.properties), not `inji-default.properties`. Common examples: + +| Property | Purpose | +| --- | --- | +| `mosip.openid.issuers` | File name for issuer configuration, usually `mimoto-issuers-config.json`. | +| `mosip.openid.verifiers` | File name for trusted verifier configuration, usually `mimoto-trusted-verifiers.json`. | +| `mosip.inji.web.url` and `mosip.inji.web.redirect.url` | Inji Web URL and redirect URL used by OVP flows. | +| `mosip.inji.qr.data.size.limit`, `mosip.inji.qr.code.height`, `mosip.inji.qr.code.width` | QR generation limits and size defaults. | +| `mosip.inji.ovp.qrdata.pattern`, `mosip.inji.ovp.redirect.url.pattern`, `mosip.inji.ovp.error.redirect.url.pattern` | OpenID4VP QR and redirect URL templates. | +| `wallet.passcode.*` | Wallet passcode retry and lock behavior. | +| `cache.*.expiry-time-in-min` | Cache expiry for issuer config and well-known responses. | + +## App Build-Time Configuration + +Some customization is build-time configuration in the mobile app, not server-side configuration: + +| Variable | Used by | Purpose | +| --- | --- | --- | +| `MIMOTO_HOST` | `shared/constants.ts` | Base URL used by wallet API calls to Mimoto. | +| `ESIGNET_HOST` | `shared/constants.ts` | Base URL used by linked authorization calls. | +| `APPLICATION_THEME` | `components/ui/styleUtils.ts`, `app.config.ts`, `SplashScreen.tsx` | Selects default vs purple theme and adaptive splash image. | +| `LIVENESS_DETECTION` | `shared/constants.ts` | Enables/disables liveness detection checks. | +| `DEBUG_MODE` | `shared/constants.ts` | Enables debug behavior in the app. | + +Keep deployment config, Mimoto config, and mobile build-time variables in sync. For example, if a deployment points the wallet at a new Mimoto base URL, the `MIMOTO_HOST` build variable and that Mimoto instance's `mimoto-issuers-config.json` must agree on issuer and token endpoints. diff --git a/inji-wallet/inji-mobile/technical-overview/customization-overview/credential_providers.md b/inji-wallet/inji-mobile/technical-overview/customization-overview/credential_providers.md index aa5bfc9..35c22e2 100644 --- a/inji-wallet/inji-mobile/technical-overview/customization-overview/credential_providers.md +++ b/inji-wallet/inji-mobile/technical-overview/customization-overview/credential_providers.md @@ -1,101 +1,143 @@ # Credential Providers -Inji Wallet currently provides support for following credential providers: +Inji Wallet Mobile gets its issuer list from Mimoto. Mimoto reads issuer definitions from [`mimoto-issuers-config.json`](https://github.com/inji/inji-config/blob/master/mimoto-issuers-config.json) in [`inji/inji-config`](https://github.com/inji/inji-config). -**Download VC using OpenID for VC Issuance Flow** +The wallet currently calls: -* National ID -* Insurance +```http +GET /v1/mimoto/issuers +GET /v1/mimoto/issuers/{issuer-id} +``` -To set up a new provider that can issue VC, it can be accomplished by making a few configuration changes. +Mimoto also has `/v2/issuers` endpoints, but the release 1.x mobile wallet code still uses the `/v1/mimoto/issuers` endpoints. -**Steps:** +## Supported Issuer Protocols -1. The configuration details can be found in the `mimoto-issuers-config.json` property file. This file is maintained separately for each deployment environment. In this repository, each environment's configuration is stored in a dedicated branch specific to that environment. +Issuer entries use the `protocol` field: -> Refer to [mimoto-issuers-config.json](https://github.com/mosip/inji-config/blob/collab/mimoto-issuers-config.json) of Collab environment. +| Protocol | Purpose | +| --- | --- | +| `OpenId4VCI` | OpenID for Verifiable Credential Issuance based credential download. | +| `OTP` | Legacy MOSIP OTP/UIN/VID/AID credential download flow. | -These values will be used by Inji Wallet via Mimoto. Mimoto exposes APIs which is used by the Inji Wallet application to fetch, store the issuers and their configurations in the local storage. +Current default issuer examples include `MosipOtp`, `Mosip`, `StayProtected`, `Mock`, `MosipTAN`, `Land`, and `MockMdl`. Environments can enable, disable, add, or remove entries according to their deployment needs. -* API used to fetch issuers: `https://api.collab.mosip.net/v1/mimoto/issuers` +## Add an OpenID4VCI Issuer -2. In `mimoto-issuers-config.json`, new providers can be added as per the `well-known` schema defined by OpenID4VCI standards. +Add a new object to the `issuers` array in `mimoto-issuers-config.json`. -After adding the provider in configuration, it will be displayed on the UI on `Add new card` screen. +Minimum fields used by the wallet and Mimoto are: -* If new provider supports [OpenID4VCI](https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html) protocol, it is recommended to use `issuerMachine.ts` for workflow to download VC. +```json +{ + "issuer_id": "ExampleIssuer", + "credential_issuer": "ExampleIssuer", + "credential_issuer_host": "https://issuer.example.org", + "display": [ + { + "name": "Example Issuer", + "logo": { + "url": "https://example.org/logo.png", + "alt_text": "Example issuer logo" + }, + "title": "Download Example Credential", + "description": "Download example credential", + "language": "en" + } + ], + "protocol": "OpenId4VCI", + "client_id": "${mimoto.oidc.example.partner.clientid}", + "client_alias": "mpartner-default-mimoto-example-oidc", + "wellknown_endpoint": "https://issuer.example.org/v1/certify/issuance/.well-known/openid-credential-issuer", + "redirect_uri": "io.mosip.residentapp.inji://oauthredirect", + "token_endpoint": "https://${mosip.api.public.host}/v1/mimoto/get-token/ExampleIssuer", + "authorization_audience": "https://auth.example.org/v1/esignet/oauth/v2/token", + "proxy_token_endpoint": "https://auth.example.org/v1/esignet/oauth/v2/token", + "qr_code_type": "OnlineSharing", + "enabled": "true" +} +``` -3. At present, Inji Wallet supports verification of VCs which has RSA proof type. If VC is issued with any other proof type, VC verification is bypassed and it is marked as verified. -4. Token endpoint should also use same issuer id. Refer https://github.com/mosip/inji-config/blob/collab/mimoto-issuers-config.json#L140 -5. Once the above steps are completed, mimoto should be onboarded as an OIDC client for every issuer. Please check the steps in the below sections. +Important rules: -### **Onboarding Mimoto as OIDC Client for a new Issuer:** +* `issuer_id` is the stable key used by wallet state and API calls. +* `token_endpoint` must use the same issuer id in `/v1/mimoto/get-token/{issuer_id}`. +* `credential_issuer_host` is used by the wallet to fetch issuer well-known metadata. +* `wellknown_endpoint` must expose OpenID4VCI issuer metadata. Inji Certify deployments usually expose this at `/v1/certify/issuance/.well-known/openid-credential-issuer`. +* `display` controls how the issuer appears on the Add New Card screen. Add one object per supported language. +* `enabled` must resolve to `true` for the issuer to appear. -#### Use mock data from collab sandbox env +After adding the issuer, restart or refresh the Mimoto deployment so it reloads the configuration. The wallet caches issuer responses, so a fresh app launch or cache expiry may be needed before the new issuer is visible. -If you are looking to try out wallet and certify building locally, then you can use collab env eSignet as authorization server. Here are the details: +## Credential Formats and Verification -1. We have configured few UINs/Individual Ids to use. These UINs can be used while configuring the data for credential. (**Few Demo UINs you can use)**: +The release 1.x wallet supports these credential formats: -
TypeUIN
Male (Adult)2154189532 , 5614273165
Female (Adult)2089250384 , 5860356276
Minor (aged btw 5-18yrs)3963293078
Infant (aged below 5 yrs)5134067562
+* `ldp_vc` +* `mso_mdoc` +* `vc+sd-jwt` +* `dc+sd-jwt` -2. Use `wallet-demo` as client id in `mimoto-issuers-config.json` -3. Use `wallet-demo-client` as client alias in `mimoto-issuers-config.json` -4. oidckeystore.p12 file is attached [**here**](https://github.com/mosip/documentation/blob/inji/docs/.gitbook/assets/oidckeystore.p12.zip) password to unlock this is `xy4gh6swa2i` -5. authorization server to use in `well-known` is `https://esignet-mock.collab.mosip.net` +For key management and signing, the wallet maps the following algorithms to local key types: -After configuring issuers and data as mentioned above, we will be able to successfully authenticate through esigent and download credential in wallet. +* `EdDSA` / `Ed25519` +* `ES256` +* `ES256K` +* `RS256` -#### Create new client-id and onboard mimoto as OIDC client +Verification is not limited to RSA proof types. On Android the wallet uses the VC verifier module for supported formats. On iOS, `mso_mdoc`, `vc+sd-jwt`, and `dc+sd-jwt` currently return a successful verification result while native verifier support is being completed, and `ldp_vc` verification uses the supported JSON-LD suites. Credential-offer verification can also be disabled by configuration through `disableCredentialOfferVcVerification`. -**Step 1:** +## Onboard Mimoto as an OIDC Client -Please find a zip file attached to this document called certgen.zip which will help the user in creating the p12 file as well as the public-key.jwk file. +Each OpenID4VCI issuer needs a corresponding OIDC client entry for Mimoto. -{% file src="../../../../.gitbook/assets/certgen.zip" %} +### Step 1: Generate the key material + +Use the provided cert generation utility to create the `oidckeystore.p12` and public JWK. -**Step 2:** +{% file src="../../../../.gitbook/assets/certgen.zip" %} -The Userguide.md file explains the working of the script. +The `Userguide.md` inside the zip explains how to run the script. -**Step 3:** +### Step 2: Create the OIDC client -Create a client ID using the Esignet API which is mentioned below: +Create a client ID using the eSignet client management API: ```js RequestURL : {{ESIGNET-URL}}/v1/esignet/client-mgmt/oidc-client ``` -**Sample Request Body:** +Sample request body: ```js - - { "requestTime": "2024-06-19T11:56:01.925Z", "request": { - "clientId": "client-id", #ClientId can be given as per user choice - "clientName": "client-name", #ClientName can be given as per user choice and this name shows on the UI - "publicKey": "public-key" #This public key you can get from the script results , - "relyingPartyId": "client-id", #This value can be same as clientId - "userClaims": [ #Claims Section defines the different attributes of User Data taht is accessible to the OIDC client - "birthdate", - "address", - "gender", - "name", - "phone_number", - "picture", - "email", - "individual_id" - ], - "authContextRefs": [ #ACR values define the various ways a user can login e.g through INJI,using Bioemtrics and Throguh OTP - "mosip:idp:acr:linked-wallet", - "mosip:idp:acr:biometrics", - "mosip:idp:acr:knowledge", - "mosip:idp:acr:generated-code" - ], - "logoUri": "logourl" #This is logo url which is displayed on UI, - "redirectUris": [ "io.mosip.residentapp.inji://oauthredirect", http://injiweb.collab.mosip.net/redirect"],#These are the redirectUris for Inji wallet mobile and web both + "clientId": "client-id", + "clientName": "client-name", + "publicKey": "public-key", + "relyingPartyId": "client-id", + "userClaims": [ + "birthdate", + "address", + "gender", + "name", + "phone_number", + "picture", + "email", + "individual_id" + ], + "authContextRefs": [ + "mosip:idp:acr:linked-wallet", + "mosip:idp:acr:biometrics", + "mosip:idp:acr:knowledge", + "mosip:idp:acr:generated-code" + ], + "logoUri": "https://example.org/logo.png", + "redirectUris": [ + "io.mosip.residentapp.inji://oauthredirect", + "https://injiweb.example.org/redirect" + ], "grantTypes": [ "authorization_code" ], @@ -104,93 +146,89 @@ RequestURL : {{ESIGNET-URL}}/v1/esignet/client-mgmt/oidc-client ] } } - ``` -**Sample Response :** +Sample response: ```js - { - "responseTime": "2024-11-13T08:16:42.259Z", - "response": { - "clientId": "client-id", - "status": "ACTIVE" - }, - "errors": [] + "responseTime": "2024-11-13T08:16:42.259Z", + "response": { + "clientId": "client-id", + "status": "ACTIVE" + }, + "errors": [] } - ``` {% hint style="info" %} -1. Clients can get renewed by demand, but that mean some manual changes are required. It is always recommended to create a client once per environment as it has no expiry. Also note that one public key and p12 file pair can be used only once . ( Unless removed from DB ) -2. The install.sh script in mimoto as well as the helm charts inside mimoto repo were changed to allow for the storage and mounting of the oidckeystore.p12 file -{% endhint %} - -**Step 4:** - -The logo URL should be uploaded to file server. - -{% hint style="info" %} -For Onboarding any new issuer, Step 1 to 4 has to be followed and p12 has to be generated. +Create one client per environment unless there is a reason to rotate it. Reusing a public key and p12 pair for multiple client registrations can fail unless the previous entry is removed from the authorization server database. {% endhint %} -**Step 5:** - -Once p12 file is generated, existing keystore file has to be exported from mimoto pod and newly created p12 file has to be imported and remounted in the Mimoto pod. +### Step 3: Update Mimoto issuer config -**Step 6:** +Set the `client_id`, `client_alias`, `authorization_audience`, `proxy_token_endpoint`, `token_endpoint`, and `wellknown_endpoint` values in the issuer entry. The client id should match the value returned by the client creation API or the deployment property referenced by the issuer config. -Once mimoto is added as an OIDC client, the new issuer should be added as a partner to mimoto. +### Step 4: Upload issuer logo -### **Using MOSIP services to issue MOSIP Credential:** +Upload the issuer logo to a publicly reachable file server and reference it from both: -1. Create a partner - following is the process of adding a new partner by the name of “esignet--partner “ onto mimoto. Refer [here](https://docs.mosip.io/1.2.0/partners#partner-onboarding) to create a partner and onboard the partner in MOSIP Ecosystem. +* `display[].logo.url` in `mimoto-issuers-config.json` +* `logoUri` in the OIDC client registration, if the authorization server consent UI should show it {% hint style="info" %} -We already have a p12 file on the mimoto pod (as explained in above section), we are not replacing or creating a second p12 file, We are only adding another key to the key-store already present. +For each new issuer, generate key material, register the OIDC client, update the issuer config, and ensure the logo URL is reachable. {% endhint %} -1. Add this newly created partner into existing keystore - download the existing p12 file from the mimoto pod using this command from the environment's terminal: +### Step 5: Mount the keystore in Mimoto + +If the deployment already has an `oidckeystore.p12`, export it from the Mimoto pod, add the new keypair as a new alias, and remount the updated keystore. ```js kubectl -n mimoto cp :certs/..data/oidckeystore.p12 oidckeystore.p12 ``` -2. Add the esignet--partner's key as alias “esignet--partner“ onto the same p12 file using a tool like keystore-explorer. Use the password used while generating p12 file +Use a keystore tool to import the new keypair into the existing p12. The alias should match the issuer's configured `client_alias`. -

Original p12 file as downloaded from environment

+Back up the original secret: -

Importing a new keypair

+```js +kubectl -n mimoto get secrets mimotooidc -o yaml | sed "s/name: mimotooidc/name: mimotooidc-backup/g" | kubectl -n mimoto create -f - +``` -3. The below image shows how to browse and select the client-id’s oidckeystore as the second alias. in the decryption password field should have the password of the p12 file. Note: we have used `esignet-sunbird-partner` as client id for reference in the attachment +Replace the secret with the updated keystore: -

Selection of OIDC Keystore

+```js +kubectl delete secret -n mimoto mimotooidc +kubectl -n mimoto create secret generic mimotooidc --from-file=./oidckeystore.p12 +``` -4. The below image shows how to add an alias for the new key pair, here the value is esignet-sunbird-partner. +Then restart the Mimoto pod. -

Alias for the new keypair

+## Using MOSIP Services to Issue MOSIP Credentials -

Add keypairs to keystore.p12

+When the issuer is backed by MOSIP services: -5. To take a backup of the original keystore.p12 use the following command +1. Create and onboard the partner in the MOSIP ecosystem. See the MOSIP partner onboarding documentation for the target MOSIP release. +2. Add the partner keypair to the existing Mimoto OIDC keystore as another alias; do not replace the whole keystore unless the deployment intends to rotate all Mimoto OIDC clients. +3. Create or update deployment secrets such as `mimoto.oidc..partner.clientid`. +4. Ensure the config-server or deployment property source exposes those values to Mimoto. +5. Restart Mimoto and verify: + * `GET /v1/mimoto/issuers` includes the issuer. + * `GET /v1/mimoto/issuers/{issuer-id}` returns the issuer details. + * The issuer well-known endpoint is reachable from the wallet/Mimoto environment. + * The Add New Card screen displays the issuer. -```js -kubectl -n mimoto get secrets mimotooidc -o yaml | sed "s/name: mimotooidc/name: mimotooidc-backup/g" | kubectl -n mimoto create -f - -``` +

Original p12 file as downloaded from environment

-6. Delete the existing mimotooidc secret using the following command +

Importing a new keypair

-```js -kubectl delete secret -n mimoto mimotooidc -``` +The image below shows how to browse and select the client id's oidckeystore as the second alias. The decryption password field should have the password of the p12 file. Note: we have used `esignet-sunbird-partner` as client id for reference in the attachment. + +

Selection of OIDC Keystore

-7. To create a new secret containing both the keypair. +The image below shows how to add an alias for the new key pair, here the value is `esignet-sunbird-partner`. -```js -kubectl -n mimoto create secret generic mimotooidc --from-file=./oidckeystore.p12 -``` +

Alias for the new keypair

-8. Create the required secrets in the cluster such as mimoto.oidc.mock.partner.clientid and use the client ID from the response of create oidc-client request. -9. Make sure to add the the mimoto.oidc.mock.partner.clientid inside the config-server deployment yaml file -10. Restart the Mimoto pod to take all the changes. +

Add keypairs to keystore.p12

diff --git a/inji-wallet/inji-mobile/technical-overview/customization-overview/locale-customization.md b/inji-wallet/inji-mobile/technical-overview/customization-overview/locale-customization.md index 59f5886..1e58247 100644 --- a/inji-wallet/inji-mobile/technical-overview/customization-overview/locale-customization.md +++ b/inji-wallet/inji-mobile/technical-overview/customization-overview/locale-customization.md @@ -1,18 +1,77 @@ # Locale customization -## Steps to Support a new language +Inji Wallet Mobile uses `i18next`, `react-i18next`, and `expo-localization`. Locale resources live in the top-level `locales` folder in the mobile wallet repo, and `i18n.ts` wires those resources into the app. -* Under `locales` folder, localization of a particular language JSON file has to be added. -* Language JSON has to be imported in `i18n.ts` and load the resources to i18next as follows. `import fil from './locales/fil.json';` `const resources = { en, fil, ar, hi, kn, ta };` -* To ensure the language needs to be included in the const `SUPPORTED_LANGUAGES`. -* To use with react, must include the key with the 't' function +## Supported Languages +The release 1.x mobile codebase currently imports these resource files: + +| App code | Resource file | Language | +| --- | --- | --- | +| `en` | `locales/en.json` | English | +| `fil` | `locales/fil.json` | Filipino | +| `ar` | `locales/ara.json` | Arabic | +| `hi` | `locales/hin.json` | Hindi | +| `kn` | `locales/kan.json` | Kannada | +| `ta` | `locales/tam.json` | Tamil | + +## Add a New Language + +1. Add a JSON resource file under `locales`, using the same namespaces and keys as `locales/en.json`. +2. Import the file in `i18n.ts`. +3. Add the imported resource to the `resources` object. +4. Add the app language code and display label to `SUPPORTED_LANGUAGES`. +5. Add translated issuer display data in `mimoto-issuers-config.json` where the Add New Card screen should show issuer names, titles, and descriptions in the new language. + +Example: + +```ts +import fr from './locales/fra.json'; + +const resources = {en, fil, ar, hi, kn, ta, fr}; + +export const SUPPORTED_LANGUAGES = { + en: 'English', + fil: 'Filipino', + ar: 'Arabic', + hi: 'Hindi', + kn: 'Kannada', + ta: 'Tamil', + fr: 'French', +}; +``` + +The display labels in `SUPPORTED_LANGUAGES` can be localized; keep the object keys aligned with the resource keys. + +Use translations through `useTranslation` or the existing `i18n.t` helpers: + +```tsx +const {t} = useTranslation('common'); + +{t('editLabel')}; ``` -const { t } = useTranslation('common'); -{t('editLabel')} +## Language Codes in Issuer Metadata + +The wallet uses two-letter language codes internally, but issuer and credential metadata may use either two-letter or three-letter codes. `i18n.ts` builds a language-code map using the `iso-639-3` package so fields such as issuer display names and localized credential values can match either form. + +When adding issuer display entries in `mimoto-issuers-config.json`, keep the `language` values consistent with the app language codes where possible: + +```json +{ + "display": [ + { + "name": "Example Issuer", + "title": "Download Example Credential", + "description": "Download example credential", + "language": "en" + } + ] +} ``` +For OpenID4VCI well-known credential metadata, use the issuer's `locale` or localized claim metadata according to the OpenID4VCI specification. The wallet falls back to English, `en-US`, or the first available entry when a language-specific display entry is not found. + ## About libraries 1. [i18next](https://www.i18next.com/) diff --git a/inji-wallet/inji-mobile/technical-overview/customization-overview/ui-customization.md b/inji-wallet/inji-mobile/technical-overview/customization-overview/ui-customization.md index f5dc436..b1f485f 100644 --- a/inji-wallet/inji-mobile/technical-overview/customization-overview/ui-customization.md +++ b/inji-wallet/inji-mobile/technical-overview/customization-overview/ui-customization.md @@ -1,221 +1,138 @@ # UI customization -## CSS Themes +## Themes -Currently, Inji Wallet supports two themes: +Inji Wallet Mobile currently ships with two theme files: -* default gradient -* purple +* `components/ui/themes/DefaultTheme.ts` +* `components/ui/themes/PurpleTheme.ts` -We can customize the application by adding a new file under `components/ui/themes` and import that file in `components/ui/styleUtils.ts` and assign that to `Theme` variable in it. Default Gradient theme is referred as DefaultTheme. +The active theme is selected in `components/ui/styleUtils.ts` from the `APPLICATION_THEME` environment variable: -``` -Example:- - components/ui/styleUtils.ts +```ts +import {DefaultTheme} from './themes/DefaultTheme'; +import {PurpleTheme} from './themes/PurpleTheme'; +import {APPLICATION_THEME} from 'react-native-dotenv'; - import { PurpleTheme } from './PurpleTheme'; - export const Theme = PurpleTheme; +export const Theme = + APPLICATION_THEME?.toLowerCase() === 'purple' ? PurpleTheme : DefaultTheme; ``` -### App Logo and Background Images +To add a new theme: -To change app logo on homescreen +1. Add a new theme file under `components/ui/themes`. +2. Keep the exported object shape compatible with `DefaultTheme` and `PurpleTheme`; `components/ui/themes/themes.test.ts` validates required properties. +3. Import the new theme in `components/ui/styleUtils.ts` and extend the `APPLICATION_THEME` selector. +4. If the splash screen should change with the theme, update `app.config.ts` as well. -``` -HomeScreenLogo: require(path of logo you want to use, in string format) in a theme file +## Logos and Background Images + +The home header logo is imported by each theme and exposed through the theme object: -Example:- +```ts import HomeScreenLogo from '../../../assets/InjiHomeLogo.svg'; + export const DefaultTheme = { - HomeScreenLogo: HomeScreenLogo - ... -} + HomeScreenLogo, + // ... +}; ``` -Profile logo is part of downloaded verifiable credential. If credential doesn't face/photo attribute, default profile icon is being used. +`HomeScreenLayout.tsx` renders the header logo through `SvgImage.InjiLogo(Theme.Styles.injiLogo)`, and the logo dimensions/spacing are controlled by `Theme.Styles.injiLogo` and `Theme.Styles.injiHomeLogo`. -To change the profile logo, In `ProfileIcon.tsx`, refer +The default profile icon is not an image asset. When a credential does not include a face/photo attribute, `components/ProfileIcon.tsx` renders the `person` icon from `react-native-elements` and colors it with `Theme.Colors.ProfileIconColor`: -``` +```tsx import {Icon} from 'react-native-elements'; -use `person` as icon from the library -``` - -Card background is driven by wellknown exposed by issuing authoriy. If background details are not exposed, default background is being used. To change card background on home screen if not provided by issuer: + ``` -CloseCard: require(path of the image you want to use, in string format) -Example:- -export const DefaultTheme = { - CloseCard: require('../../../assets/Card_Bg1.png'), - ... -} -``` - -To change background on card details screen if not provided by issuer +VC card logos, background colors, text colors, and claims come from the issuer well-known metadata when the issuer provides them. The wallet fetches the issuer metadata through `shared/openId4VCI/Utils.ts` and uses the matching credential configuration for rendering. -``` -OpenCard: require(path of the image you want to use, in string format) +If issuer metadata does not provide enough display information, the theme fallback images are used: -Example:- +```ts export const DefaultTheme = { - OpenCard: require('../../../assets/Card_Bg1.png'), - ... -} -``` - -To change the top header icons: - -![](../../../../.gitbook/assets/header_icons.png) - -In `HomeScreenLayout.tsx`, refer - -``` - var HomeScreenOptions = { - headerLeft: () => - isIOS() || !isRTL - ? SvgImage.InjiLogo(Theme.Styles.injiLogo) - : screenOptions, - headerTitle: '', - headerRight: () => - isIOS() || !isRTL - ? screenOptions - : SvgImage.InjiLogo(Theme.Styles.injiLogo), - }; + CloseCard: require('../../../assets/images/png/CardBGLandscape.png'), + OpenCard: require('../../../assets/images/png/CardBGPortrait.png'), + // ... +}; ``` -### Colours - -To change the text, colour and logo for Tabs: +## Header and Tab Icons -![](../../../../.gitbook/assets/bottom_tabs.png) +Most app icons are SVG components imported in `components/ui/svg.tsx`. Bottom tab entries are defined in `routes/main.ts`, and the tab renderer in `screens/MainLayout.tsx` resolves each icon through `SvgImage[route.name]`. -In `main.ts`, there are 4 tab screens variables - -``` -const home: TabScreen -const scan: TabScreen -const history: TabScreen -const settings: TabScreen +For example, the shipped bottom tabs are: -``` - -`image` can be changed by `icon` attribute, `text` and `styles` can be changed by `options` attribute in `MainLayout.tsx` while rendering `Navigator` - -``` -Example:- -const history: TabScreen = { - name: BOTTOM_TAB_ROUTES.history, - component: HistoryScreen, - icon: 'history', +```ts +const home: TabScreen = { + name: BOTTOM_TAB_ROUTES.home, + component: HomeScreenLayout, + icon: 'home', options: { - headerTitleStyle: Theme.Styles.HistoryHeaderTitleStyle, - title: i18n.t('MainLayout:history'), + headerTitle: '', + headerShown: false, }, }; ``` -Card content text color is driven by wellknown exposed by issuing authoriy. If text color is not exposed, default color is being used. To change default Label text color if not provided by issuer: +To add or replace a tab: -``` -export const DefaultTheme = { - Colors: { - DetailsLabel: Colors.Gray40, - ... - } -} -``` +1. Add or replace the route in `routes/main.ts`. +2. Add the matching SVG method in `components/ui/svg.tsx`. +3. Add localized tab labels in the locale JSON files under `locales`. +4. Adjust tab colors, active backgrounds, labels, and spacing in `Theme.BottomTabBarStyle`, `Theme.Styles.bottomTabIconStyle`, and `Theme.Colors.GradientColorsLight`. -To change default Label value color if not provided by issuer: +## Colors and Typography -``` -export const DefaultTheme = { - Colors: { - Details: Colors.Black, - ... - } -} -``` +Colors and typography are controlled by each theme object. Commonly customized keys include: -To change the colour of `+` icon colour: +| Area | Theme keys | +| --- | --- | +| Bottom tabs | `TabItemText`, `IconBg`, `GradientColorsLight`, `bottomTabIconStyle`, `BottomTabBarStyle` | +| VC card text fallback | `Details`, `DetailsLabel`, `fieldItemTitle`, `fieldItemValue` | +| Buttons and gradients | `gradientBtn`, `linearGradientStart`, `linearGradientEnd`, `LinearGradientDirection` | +| Settings screen | `settingsLabel`, `textLabel`, `textValue`, `AboutInjiScreenStyle` | +| Add credential flow | `IssuersScreenStyles`, `issuerLogo`, `issuersContainer`, `issuersSearchSubText` | +| Status and warnings | `WarningIcon`, `warningLogoBgColor`, `StatusInfoModalStyles`, `ToastItemText` | -In `HomeScreen.tsx`, refer `DownloadFABIcon` component +Example: -``` -const DownloadFABIcon: React.FC = () => { - const plusIcon -.... -} -``` - -To change the colours of Label in Settings: - -``` +```ts export const DefaultTheme = { Colors: { - settingsLabel: Colors.Black, - textLabel: Colors.Grey, - ... - } -} -``` - -To change the background and label colour for version section: - -![](../../../../.gitbook/assets/about-version.png) - -``` -export const DefaultTheme = { - Colors: { - aboutVersion: Colors.Gray40, - ... + DetailsLabel: Colors.Gray40, + Details: Colors.Black, + settingsLabel: Colors.Black, + textLabel: Colors.Grey, + // ... + }, + Styles: StyleSheet.create({ + versionContainer: { + backgroundColor: Colors.Grey6, + margin: 4, + borderRadius: 14, }, - Styles: StyleSheet.create({ - versionContainer: { - backgroundColor: Colors.Grey6, - margin: 4, - borderRadius: 14, - } - ... - }) -} + // ... + }), +}; ``` -To change colour on add new card page: - -``` -export const DefaultTheme = { - Styles: StyleSheet.create({ - issuerHeading: { - fontFamily: 'Inter_600SemiBold', - fontSize: 14, - paddingHorizontal: 3, - marginBottom: 2, - marginTop: 5, - }, - issuerDescription: { - fontSize: 11, - lineHeight: 14, - color: Colors.ShadeOfGrey, - paddingVertical: 5, - paddingHorizontal: 3, - paddingTop: 1.4, - } - ... - }) -} -``` +## VC Card Customization -## VC Card Customization: +VC card rendering is driven first by the credential issuer metadata exposed in the issuer's OpenID4VCI well-known endpoint. The wallet uses this metadata to select display fields and rendering hints for `ldp_vc`, `mso_mdoc`, `vc+sd-jwt`, and `dc+sd-jwt` credentials. -The VC can be dynamically rendered with all the fields, and if the display properties provided in the[ .well-known](https://injicertify-mosipid.collab.mosip.net/v1/certify/issuance/.well-known/openid-credential-issuer), Inji Wallet downloads the `.well-known` and applies the below properties on the VC template to modify the VC render. +For OpenID4VCI Final 1.0 issuers, the wallet reads `credential_configurations_supported..credential_metadata.display` and `credential_metadata.claims`. Legacy issuers that still expose `display`, `claims`, `credential_definition`, or `order` at the top level are handled by fallback parsing. -* Text colour -* Background colour -* Logo change +Issuer display metadata can include name, logo, background color, and text color: -``` +```json { "display": [ { @@ -231,3 +148,5 @@ The VC can be dynamically rendered with all the fields, and if the display prope ] } ``` + +If issuer metadata is missing or cannot be parsed, the wallet falls back to the theme defaults described above. diff --git a/inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md b/inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md index 0aa6c5e..9a44649 100644 --- a/inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md +++ b/inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md @@ -4,7 +4,7 @@ Every user journey in **Inji Wallet** (release **1.x**) — onboarding, downloading a credential, sharing it online or offline, backing it up, logging in with a QR code — is modelled as a **finite-state machine (FSM)**. Modelling flows as state machines keeps the behaviour explicit and predictable: at any point in time the app is in exactly one well-defined state, and it can only move to another state in response to a known event. -The state machines are written with [**XState v4**](https://xstate.js.org/docs/) (`xstate@^4.35.0`) and live in the [`machines/`](https://github.com/mosip/inji-wallet/tree/master/machines) folder of the Inji Wallet codebase. A few very screen-specific machines live under `screens/`, but the reusable, customizable workflow logic is concentrated in `machines/`. +The state machines are written with [**XState v4**](https://xstate.js.org/docs/) (`xstate@^4.35.0`) and live in the [`machines/`](https://github.com/inji/inji-wallet/tree/master/machines) folder of the Inji Wallet codebase. A few very screen-specific machines live under `screens/`, but the reusable, customizable workflow logic is concentrated in `machines/`. Implementers can reuse the existing machines as-is, extend them (add states, actions, guards, or services), or replace a whole flow with their own machine — this page explains how the machines are structured and wired together so you can do that confidently. From d679b028b151dae6fb349330a4d3fb557d15e58d Mon Sep 17 00:00:00 2001 From: abhip2565 Date: Wed, 8 Jul 2026 17:51:16 +0530 Subject: [PATCH 6/7] docs(inji-mobile): address customization review comments Signed-off-by: abhip2565 --- .../customization-overview/README.md | 2 +- .../customization-overview/configuration.md | 14 +- .../credential_providers.md | 260 ++++++++---------- .../locale-customization.md | 2 +- .../workflow-customization.md | 4 +- 5 files changed, 124 insertions(+), 158 deletions(-) diff --git a/inji-wallet/inji-mobile/technical-overview/customization-overview/README.md b/inji-wallet/inji-mobile/technical-overview/customization-overview/README.md index 59468f4..d343cba 100644 --- a/inji-wallet/inji-mobile/technical-overview/customization-overview/README.md +++ b/inji-wallet/inji-mobile/technical-overview/customization-overview/README.md @@ -1,6 +1,6 @@ # Customizations -Implementers can customize Inji Wallet Mobile for their deployment, issuer set, supported languages, and branding. The pages in this section describe the extension points that are still current for the release 1.x mobile codebase. +Countries also have the option to customize Inji as per their requirements. Refer to the documents below for more information on the same. The following customizations are available in Inji: diff --git a/inji-wallet/inji-mobile/technical-overview/customization-overview/configuration.md b/inji-wallet/inji-mobile/technical-overview/customization-overview/configuration.md index 2ab399c..0d1defa 100644 --- a/inji-wallet/inji-mobile/technical-overview/customization-overview/configuration.md +++ b/inji-wallet/inji-mobile/technical-overview/customization-overview/configuration.md @@ -2,21 +2,25 @@ ## Configuration for Inji Wallet -The configurable properties for Inji Wallet Mobile are maintained in [`inji/inji-config`](https://github.com/inji/inji-config), primarily in [`inji-default.properties`](https://github.com/inji/inji-config/blob/master/inji-default.properties). Deployment environments can override these values through their config branch or deployment-specific property source. +The configurable properties for Inji Wallet can be found at [inji-default.properties](https://github.com/mosip/inji-config/blob/master/inji-default.properties). This property file is maintained as one for each deployment environment. On [this](https://github.com/mosip/inji-config) repository, each environment configuration is placed in a corresponding branch specific to that environment. -Mimoto loads these `mosip.inji.*` properties and exposes them to the wallet through: +> Refer to [inji-default.properties](https://github.com/mosip/inji-config/blob/collab/inji-default.properties) of Collab environment. + +These values will be used by Inji Wallet via Mimoto. Mimoto loads all the configurations and exposes an API which is used by the Inji Wallet application to fetch and store the configurations in the local storage. + +API used to fetch these configurations: ```http GET /v1/mimoto/allProperties ``` -For example, in a deployment whose Mimoto base URL is `https://api.collab.mosip.net`, the wallet calls: +For example, in the Collab environment: ```text https://api.collab.mosip.net/v1/mimoto/allProperties ``` -The wallet caches the response locally and falls back to `shared/InitialConfig.ts` on first launch if the API is unavailable. +The implementers can choose to use the existing configurations or add new configurations to them. ## Properties Used by Mobile @@ -64,4 +68,4 @@ Some customization is build-time configuration in the mobile app, not server-sid | `LIVENESS_DETECTION` | `shared/constants.ts` | Enables/disables liveness detection checks. | | `DEBUG_MODE` | `shared/constants.ts` | Enables debug behavior in the app. | -Keep deployment config, Mimoto config, and mobile build-time variables in sync. For example, if a deployment points the wallet at a new Mimoto base URL, the `MIMOTO_HOST` build variable and that Mimoto instance's `mimoto-issuers-config.json` must agree on issuer and token endpoints. +Keep deployment config, Mimoto config, and mobile build-time variables in sync. `MIMOTO_HOST` only sets the wallet's Mimoto base URL; issuer and token endpoints are configured on the Mimoto side, primarily through `mimoto-issuers-config.json`, and must be valid for the selected Mimoto deployment. diff --git a/inji-wallet/inji-mobile/technical-overview/customization-overview/credential_providers.md b/inji-wallet/inji-mobile/technical-overview/customization-overview/credential_providers.md index 35c22e2..aa5bfc9 100644 --- a/inji-wallet/inji-mobile/technical-overview/customization-overview/credential_providers.md +++ b/inji-wallet/inji-mobile/technical-overview/customization-overview/credential_providers.md @@ -1,143 +1,101 @@ # Credential Providers -Inji Wallet Mobile gets its issuer list from Mimoto. Mimoto reads issuer definitions from [`mimoto-issuers-config.json`](https://github.com/inji/inji-config/blob/master/mimoto-issuers-config.json) in [`inji/inji-config`](https://github.com/inji/inji-config). +Inji Wallet currently provides support for following credential providers: -The wallet currently calls: +**Download VC using OpenID for VC Issuance Flow** -```http -GET /v1/mimoto/issuers -GET /v1/mimoto/issuers/{issuer-id} -``` +* National ID +* Insurance -Mimoto also has `/v2/issuers` endpoints, but the release 1.x mobile wallet code still uses the `/v1/mimoto/issuers` endpoints. +To set up a new provider that can issue VC, it can be accomplished by making a few configuration changes. -## Supported Issuer Protocols +**Steps:** -Issuer entries use the `protocol` field: +1. The configuration details can be found in the `mimoto-issuers-config.json` property file. This file is maintained separately for each deployment environment. In this repository, each environment's configuration is stored in a dedicated branch specific to that environment. -| Protocol | Purpose | -| --- | --- | -| `OpenId4VCI` | OpenID for Verifiable Credential Issuance based credential download. | -| `OTP` | Legacy MOSIP OTP/UIN/VID/AID credential download flow. | +> Refer to [mimoto-issuers-config.json](https://github.com/mosip/inji-config/blob/collab/mimoto-issuers-config.json) of Collab environment. -Current default issuer examples include `MosipOtp`, `Mosip`, `StayProtected`, `Mock`, `MosipTAN`, `Land`, and `MockMdl`. Environments can enable, disable, add, or remove entries according to their deployment needs. +These values will be used by Inji Wallet via Mimoto. Mimoto exposes APIs which is used by the Inji Wallet application to fetch, store the issuers and their configurations in the local storage. -## Add an OpenID4VCI Issuer +* API used to fetch issuers: `https://api.collab.mosip.net/v1/mimoto/issuers` -Add a new object to the `issuers` array in `mimoto-issuers-config.json`. +2. In `mimoto-issuers-config.json`, new providers can be added as per the `well-known` schema defined by OpenID4VCI standards. -Minimum fields used by the wallet and Mimoto are: +After adding the provider in configuration, it will be displayed on the UI on `Add new card` screen. -```json -{ - "issuer_id": "ExampleIssuer", - "credential_issuer": "ExampleIssuer", - "credential_issuer_host": "https://issuer.example.org", - "display": [ - { - "name": "Example Issuer", - "logo": { - "url": "https://example.org/logo.png", - "alt_text": "Example issuer logo" - }, - "title": "Download Example Credential", - "description": "Download example credential", - "language": "en" - } - ], - "protocol": "OpenId4VCI", - "client_id": "${mimoto.oidc.example.partner.clientid}", - "client_alias": "mpartner-default-mimoto-example-oidc", - "wellknown_endpoint": "https://issuer.example.org/v1/certify/issuance/.well-known/openid-credential-issuer", - "redirect_uri": "io.mosip.residentapp.inji://oauthredirect", - "token_endpoint": "https://${mosip.api.public.host}/v1/mimoto/get-token/ExampleIssuer", - "authorization_audience": "https://auth.example.org/v1/esignet/oauth/v2/token", - "proxy_token_endpoint": "https://auth.example.org/v1/esignet/oauth/v2/token", - "qr_code_type": "OnlineSharing", - "enabled": "true" -} -``` +* If new provider supports [OpenID4VCI](https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html) protocol, it is recommended to use `issuerMachine.ts` for workflow to download VC. -Important rules: +3. At present, Inji Wallet supports verification of VCs which has RSA proof type. If VC is issued with any other proof type, VC verification is bypassed and it is marked as verified. +4. Token endpoint should also use same issuer id. Refer https://github.com/mosip/inji-config/blob/collab/mimoto-issuers-config.json#L140 +5. Once the above steps are completed, mimoto should be onboarded as an OIDC client for every issuer. Please check the steps in the below sections. -* `issuer_id` is the stable key used by wallet state and API calls. -* `token_endpoint` must use the same issuer id in `/v1/mimoto/get-token/{issuer_id}`. -* `credential_issuer_host` is used by the wallet to fetch issuer well-known metadata. -* `wellknown_endpoint` must expose OpenID4VCI issuer metadata. Inji Certify deployments usually expose this at `/v1/certify/issuance/.well-known/openid-credential-issuer`. -* `display` controls how the issuer appears on the Add New Card screen. Add one object per supported language. -* `enabled` must resolve to `true` for the issuer to appear. +### **Onboarding Mimoto as OIDC Client for a new Issuer:** -After adding the issuer, restart or refresh the Mimoto deployment so it reloads the configuration. The wallet caches issuer responses, so a fresh app launch or cache expiry may be needed before the new issuer is visible. +#### Use mock data from collab sandbox env -## Credential Formats and Verification +If you are looking to try out wallet and certify building locally, then you can use collab env eSignet as authorization server. Here are the details: -The release 1.x wallet supports these credential formats: +1. We have configured few UINs/Individual Ids to use. These UINs can be used while configuring the data for credential. (**Few Demo UINs you can use)**: -* `ldp_vc` -* `mso_mdoc` -* `vc+sd-jwt` -* `dc+sd-jwt` +
TypeUIN
Male (Adult)2154189532 , 5614273165
Female (Adult)2089250384 , 5860356276
Minor (aged btw 5-18yrs)3963293078
Infant (aged below 5 yrs)5134067562
-For key management and signing, the wallet maps the following algorithms to local key types: +2. Use `wallet-demo` as client id in `mimoto-issuers-config.json` +3. Use `wallet-demo-client` as client alias in `mimoto-issuers-config.json` +4. oidckeystore.p12 file is attached [**here**](https://github.com/mosip/documentation/blob/inji/docs/.gitbook/assets/oidckeystore.p12.zip) password to unlock this is `xy4gh6swa2i` +5. authorization server to use in `well-known` is `https://esignet-mock.collab.mosip.net` -* `EdDSA` / `Ed25519` -* `ES256` -* `ES256K` -* `RS256` +After configuring issuers and data as mentioned above, we will be able to successfully authenticate through esigent and download credential in wallet. -Verification is not limited to RSA proof types. On Android the wallet uses the VC verifier module for supported formats. On iOS, `mso_mdoc`, `vc+sd-jwt`, and `dc+sd-jwt` currently return a successful verification result while native verifier support is being completed, and `ldp_vc` verification uses the supported JSON-LD suites. Credential-offer verification can also be disabled by configuration through `disableCredentialOfferVcVerification`. +#### Create new client-id and onboard mimoto as OIDC client -## Onboard Mimoto as an OIDC Client +**Step 1:** -Each OpenID4VCI issuer needs a corresponding OIDC client entry for Mimoto. - -### Step 1: Generate the key material - -Use the provided cert generation utility to create the `oidckeystore.p12` and public JWK. +Please find a zip file attached to this document called certgen.zip which will help the user in creating the p12 file as well as the public-key.jwk file. {% file src="../../../../.gitbook/assets/certgen.zip" %} -The `Userguide.md` inside the zip explains how to run the script. +**Step 2:** + +The Userguide.md file explains the working of the script. -### Step 2: Create the OIDC client +**Step 3:** -Create a client ID using the eSignet client management API: +Create a client ID using the Esignet API which is mentioned below: ```js RequestURL : {{ESIGNET-URL}}/v1/esignet/client-mgmt/oidc-client ``` -Sample request body: +**Sample Request Body:** ```js + + { "requestTime": "2024-06-19T11:56:01.925Z", "request": { - "clientId": "client-id", - "clientName": "client-name", - "publicKey": "public-key", - "relyingPartyId": "client-id", - "userClaims": [ - "birthdate", - "address", - "gender", - "name", - "phone_number", - "picture", - "email", - "individual_id" - ], - "authContextRefs": [ - "mosip:idp:acr:linked-wallet", - "mosip:idp:acr:biometrics", - "mosip:idp:acr:knowledge", - "mosip:idp:acr:generated-code" - ], - "logoUri": "https://example.org/logo.png", - "redirectUris": [ - "io.mosip.residentapp.inji://oauthredirect", - "https://injiweb.example.org/redirect" - ], + "clientId": "client-id", #ClientId can be given as per user choice + "clientName": "client-name", #ClientName can be given as per user choice and this name shows on the UI + "publicKey": "public-key" #This public key you can get from the script results , + "relyingPartyId": "client-id", #This value can be same as clientId + "userClaims": [ #Claims Section defines the different attributes of User Data taht is accessible to the OIDC client + "birthdate", + "address", + "gender", + "name", + "phone_number", + "picture", + "email", + "individual_id" + ], + "authContextRefs": [ #ACR values define the various ways a user can login e.g through INJI,using Bioemtrics and Throguh OTP + "mosip:idp:acr:linked-wallet", + "mosip:idp:acr:biometrics", + "mosip:idp:acr:knowledge", + "mosip:idp:acr:generated-code" + ], + "logoUri": "logourl" #This is logo url which is displayed on UI, + "redirectUris": [ "io.mosip.residentapp.inji://oauthredirect", http://injiweb.collab.mosip.net/redirect"],#These are the redirectUris for Inji wallet mobile and web both "grantTypes": [ "authorization_code" ], @@ -146,89 +104,93 @@ Sample request body: ] } } + ``` -Sample response: +**Sample Response :** ```js + { - "responseTime": "2024-11-13T08:16:42.259Z", - "response": { - "clientId": "client-id", - "status": "ACTIVE" - }, - "errors": [] + "responseTime": "2024-11-13T08:16:42.259Z", + "response": { + "clientId": "client-id", + "status": "ACTIVE" + }, + "errors": [] } + ``` {% hint style="info" %} -Create one client per environment unless there is a reason to rotate it. Reusing a public key and p12 pair for multiple client registrations can fail unless the previous entry is removed from the authorization server database. +1. Clients can get renewed by demand, but that mean some manual changes are required. It is always recommended to create a client once per environment as it has no expiry. Also note that one public key and p12 file pair can be used only once . ( Unless removed from DB ) +2. The install.sh script in mimoto as well as the helm charts inside mimoto repo were changed to allow for the storage and mounting of the oidckeystore.p12 file {% endhint %} -### Step 3: Update Mimoto issuer config - -Set the `client_id`, `client_alias`, `authorization_audience`, `proxy_token_endpoint`, `token_endpoint`, and `wellknown_endpoint` values in the issuer entry. The client id should match the value returned by the client creation API or the deployment property referenced by the issuer config. +**Step 4:** -### Step 4: Upload issuer logo - -Upload the issuer logo to a publicly reachable file server and reference it from both: - -* `display[].logo.url` in `mimoto-issuers-config.json` -* `logoUri` in the OIDC client registration, if the authorization server consent UI should show it +The logo URL should be uploaded to file server. {% hint style="info" %} -For each new issuer, generate key material, register the OIDC client, update the issuer config, and ensure the logo URL is reachable. +For Onboarding any new issuer, Step 1 to 4 has to be followed and p12 has to be generated. {% endhint %} -### Step 5: Mount the keystore in Mimoto +**Step 5:** -If the deployment already has an `oidckeystore.p12`, export it from the Mimoto pod, add the new keypair as a new alias, and remount the updated keystore. +Once p12 file is generated, existing keystore file has to be exported from mimoto pod and newly created p12 file has to be imported and remounted in the Mimoto pod. -```js -kubectl -n mimoto cp :certs/..data/oidckeystore.p12 oidckeystore.p12 -``` +**Step 6:** -Use a keystore tool to import the new keypair into the existing p12. The alias should match the issuer's configured `client_alias`. +Once mimoto is added as an OIDC client, the new issuer should be added as a partner to mimoto. -Back up the original secret: +### **Using MOSIP services to issue MOSIP Credential:** -```js -kubectl -n mimoto get secrets mimotooidc -o yaml | sed "s/name: mimotooidc/name: mimotooidc-backup/g" | kubectl -n mimoto create -f - -``` +1. Create a partner - following is the process of adding a new partner by the name of “esignet--partner “ onto mimoto. Refer [here](https://docs.mosip.io/1.2.0/partners#partner-onboarding) to create a partner and onboard the partner in MOSIP Ecosystem. -Replace the secret with the updated keystore: +{% hint style="info" %} +We already have a p12 file on the mimoto pod (as explained in above section), we are not replacing or creating a second p12 file, We are only adding another key to the key-store already present. +{% endhint %} + +1. Add this newly created partner into existing keystore - download the existing p12 file from the mimoto pod using this command from the environment's terminal: ```js -kubectl delete secret -n mimoto mimotooidc -kubectl -n mimoto create secret generic mimotooidc --from-file=./oidckeystore.p12 +kubectl -n mimoto cp :certs/..data/oidckeystore.p12 oidckeystore.p12 ``` -Then restart the Mimoto pod. - -## Using MOSIP Services to Issue MOSIP Credentials - -When the issuer is backed by MOSIP services: - -1. Create and onboard the partner in the MOSIP ecosystem. See the MOSIP partner onboarding documentation for the target MOSIP release. -2. Add the partner keypair to the existing Mimoto OIDC keystore as another alias; do not replace the whole keystore unless the deployment intends to rotate all Mimoto OIDC clients. -3. Create or update deployment secrets such as `mimoto.oidc..partner.clientid`. -4. Ensure the config-server or deployment property source exposes those values to Mimoto. -5. Restart Mimoto and verify: - * `GET /v1/mimoto/issuers` includes the issuer. - * `GET /v1/mimoto/issuers/{issuer-id}` returns the issuer details. - * The issuer well-known endpoint is reachable from the wallet/Mimoto environment. - * The Add New Card screen displays the issuer. +2. Add the esignet--partner's key as alias “esignet--partner“ onto the same p12 file using a tool like keystore-explorer. Use the password used while generating p12 file

Original p12 file as downloaded from environment

Importing a new keypair

-The image below shows how to browse and select the client id's oidckeystore as the second alias. The decryption password field should have the password of the p12 file. Note: we have used `esignet-sunbird-partner` as client id for reference in the attachment. +3. The below image shows how to browse and select the client-id’s oidckeystore as the second alias. in the decryption password field should have the password of the p12 file. Note: we have used `esignet-sunbird-partner` as client id for reference in the attachment

Selection of OIDC Keystore

-The image below shows how to add an alias for the new key pair, here the value is `esignet-sunbird-partner`. +4. The below image shows how to add an alias for the new key pair, here the value is esignet-sunbird-partner.

Alias for the new keypair

Add keypairs to keystore.p12

+ +5. To take a backup of the original keystore.p12 use the following command + +```js +kubectl -n mimoto get secrets mimotooidc -o yaml | sed "s/name: mimotooidc/name: mimotooidc-backup/g" | kubectl -n mimoto create -f - +``` + +6. Delete the existing mimotooidc secret using the following command + +```js +kubectl delete secret -n mimoto mimotooidc +``` + +7. To create a new secret containing both the keypair. + +```js +kubectl -n mimoto create secret generic mimotooidc --from-file=./oidckeystore.p12 +``` + +8. Create the required secrets in the cluster such as mimoto.oidc.mock.partner.clientid and use the client ID from the response of create oidc-client request. +9. Make sure to add the the mimoto.oidc.mock.partner.clientid inside the config-server deployment yaml file +10. Restart the Mimoto pod to take all the changes. diff --git a/inji-wallet/inji-mobile/technical-overview/customization-overview/locale-customization.md b/inji-wallet/inji-mobile/technical-overview/customization-overview/locale-customization.md index 1e58247..0a86526 100644 --- a/inji-wallet/inji-mobile/technical-overview/customization-overview/locale-customization.md +++ b/inji-wallet/inji-mobile/technical-overview/customization-overview/locale-customization.md @@ -4,7 +4,7 @@ Inji Wallet Mobile uses `i18next`, `react-i18next`, and `expo-localization`. Loc ## Supported Languages -The release 1.x mobile codebase currently imports these resource files: +The mobile codebase currently imports these resource files: | App code | Resource file | Language | | --- | --- | --- | diff --git a/inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md b/inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md index 9a44649..c4d1387 100644 --- a/inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md +++ b/inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md @@ -2,7 +2,7 @@ ## Overview -Every user journey in **Inji Wallet** (release **1.x**) — onboarding, downloading a credential, sharing it online or offline, backing it up, logging in with a QR code — is modelled as a **finite-state machine (FSM)**. Modelling flows as state machines keeps the behaviour explicit and predictable: at any point in time the app is in exactly one well-defined state, and it can only move to another state in response to a known event. +Every user journey in **Inji Wallet** — onboarding, downloading a credential, sharing it online or offline, backing it up, logging in with a QR code — is modelled as a **finite-state machine (FSM)**. Modelling flows as state machines keeps the behaviour explicit and predictable: at any point in time the app is in exactly one well-defined state, and it can only move to another state in response to a known event. The state machines are written with [**XState v4**](https://xstate.js.org/docs/) (`xstate@^4.35.0`) and live in the [`machines/`](https://github.com/inji/inji-wallet/tree/master/machines) folder of the Inji Wallet codebase. A few very screen-specific machines live under `screens/`, but the reusable, customizable workflow logic is concentrated in `machines/`. @@ -16,7 +16,7 @@ XState is a data structure + interpreter. Editing a machine is mostly editing a Inji Wallet uses a **multi-actor** architecture. A root machine boots the app and **spawns** long-lived child machines ("service actors"). These references are kept in a shared context object (`AppServices`, exposed through `shared/GlobalContext`) so any part of the app can `send` events to any machine. -``` +```text app.ts (root) │ ├── store → machines/store.ts (spawned first — storage/crypto gateway) From d8787244fc36c9f0f36f5b76242803ba1a474220 Mon Sep 17 00:00:00 2001 From: abhip2565 Date: Thu, 9 Jul 2026 11:10:58 +0530 Subject: [PATCH 7/7] docs(inji-mobile): fix broken customization links and drop issuer step Signed-off-by: abhip2565 --- .../customization-overview/configuration.md | 4 ++-- .../customization-overview/locale-customization.md | 1 - .../customization-overview/workflow-customization.md | 10 +++++----- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/inji-wallet/inji-mobile/technical-overview/customization-overview/configuration.md b/inji-wallet/inji-mobile/technical-overview/customization-overview/configuration.md index 0d1defa..669c2ef 100644 --- a/inji-wallet/inji-mobile/technical-overview/customization-overview/configuration.md +++ b/inji-wallet/inji-mobile/technical-overview/customization-overview/configuration.md @@ -2,9 +2,9 @@ ## Configuration for Inji Wallet -The configurable properties for Inji Wallet can be found at [inji-default.properties](https://github.com/mosip/inji-config/blob/master/inji-default.properties). This property file is maintained as one for each deployment environment. On [this](https://github.com/mosip/inji-config) repository, each environment configuration is placed in a corresponding branch specific to that environment. +The configurable properties for Inji Wallet can be found at [inji-default.properties](https://github.com/inji/inji-config/blob/master/inji-default.properties). This property file is maintained as one for each deployment environment. On [this](https://github.com/inji/inji-config) repository, each environment configuration is placed in a corresponding branch specific to that environment. -> Refer to [inji-default.properties](https://github.com/mosip/inji-config/blob/collab/inji-default.properties) of Collab environment. +> Refer to [inji-default.properties](https://github.com/inji/inji-config/blob/collab/inji-default.properties) of Collab environment. These values will be used by Inji Wallet via Mimoto. Mimoto loads all the configurations and exposes an API which is used by the Inji Wallet application to fetch and store the configurations in the local storage. diff --git a/inji-wallet/inji-mobile/technical-overview/customization-overview/locale-customization.md b/inji-wallet/inji-mobile/technical-overview/customization-overview/locale-customization.md index 0a86526..d504e1b 100644 --- a/inji-wallet/inji-mobile/technical-overview/customization-overview/locale-customization.md +++ b/inji-wallet/inji-mobile/technical-overview/customization-overview/locale-customization.md @@ -21,7 +21,6 @@ The mobile codebase currently imports these resource files: 2. Import the file in `i18n.ts`. 3. Add the imported resource to the `resources` object. 4. Add the app language code and display label to `SUPPORTED_LANGUAGES`. -5. Add translated issuer display data in `mimoto-issuers-config.json` where the Add New Card screen should show issuer names, titles, and descriptions in the new language. Example: diff --git a/inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md b/inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md index c4d1387..fc364ec 100644 --- a/inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md +++ b/inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md @@ -103,7 +103,7 @@ The single gateway for all persistence. It exposes `GET`/`SET`/`APPEND`/`REMOVE` * [`react-native-mmkv-storage`](https://github.com/ammarahm-ed/react-native-mmkv-storage) — stores metadata and references to encrypted VCs. * [`react-native-fs`](https://www.npmjs.com/package/react-native-fs) — stores each encrypted VC as a separate file. -Key material is held in the hardware-backed keystore (see [Secure Keystore](../integration-guide/secure-keystore.md)). +Key material is held in the hardware-backed keystore (see [Secure Keystore](../integration-guide/building-verifiable-credentials-wallet-with-inji-libraries/secure-keystore.md)). ### auth.ts @@ -133,7 +133,7 @@ Owns the **entire OpenID4VCI download journey**. It calls Mimoto's `/issuers` an * performs OIDC authorization (authorization-code and pre-authorized/credential-offer flows, including transaction-code / `tx_code` prompts), * generates the key pair and builds the proof JWT for the credential request, -* downloads the credential via the [VCI-Client SDK](../integration-guide/vci-client.md), +* downloads the credential via the [VCI-Client SDK](../integration-guide/building-verifiable-credentials-wallet-with-inji-libraries/vci-client.md), * verifies the credential, and * hands it to `vcMeta`/`store` to be persisted. @@ -171,7 +171,7 @@ Spawned **once per credential**, this machine tracks a single VC's lifecycle: lo ### openID4VP/openID4VPMachine -Drives **online credential presentation** using OpenID4VP (via the [OpenID4VP SDK](../integration-guide/openid4vp.md)). It receives the authorization request (scanned or via deep link), lets the user select which VC(s) to present, optionally performs **face authentication** (share-with-selfie) through `faceScanner`, constructs and sends the Verifiable Presentation to the verifier, and logs the activity. +Drives **online credential presentation** using OpenID4VP (via the [OpenID4VP SDK](../integration-guide/building-verifiable-credentials-wallet-with-inji-libraries/openid4vp.md)). It receives the authorization request (scanned or via deep link), lets the user select which VC(s) to present, optionally performs **face authentication** (share-with-selfie) through `faceScanner`, constructs and sends the Verifiable Presentation to the verifier, and logs the activity. **Flows covered:** @@ -181,7 +181,7 @@ Drives **online credential presentation** using OpenID4VP (via the [OpenID4VP SD ## Offline sharing — BLE (Tuvali) -Offline sharing uses the [Tuvali BLE SDK](../integration-guide/tuvali/) and the [BLE Verifier](../integration-guide/ble-verifier.md) integration. +Offline sharing uses the [Tuvali BLE SDK](../integration-guide/building-verifiable-credentials-wallet-with-inji-libraries/tuvali/) and the [BLE Verifier](../integration-guide/building-verifiable-credentials-wallet-with-inji-libraries/ble-verifier.md) integration. ### bleShare/scan/scanMachine.ts @@ -219,7 +219,7 @@ Powers **"Login with QR code"** on portals that support OpenID Connect with Inji ### faceScanner.ts -Encapsulates the face-capture interaction. It is reused wherever face authentication is required — share-with-selfie (both online OpenID4VP and offline BLE flows). See the [Face Match integration](../integration-guide/face-match.md). +Encapsulates the face-capture interaction. It is reused wherever face authentication is required — share-with-selfie (both online OpenID4VP and offline BLE flows). See the [Face Match integration](../integration-guide/building-verifiable-credentials-wallet-with-inji-libraries/face-match.md). ## Backup & Restore