Credential Import And Wallets
The UI now supports importing verified credential data directly into profile forms.
This capability is intentionally provider-agnostic. The form page does not know how a wallet or external credential source works. It only knows how to:
- open the import modal
- pass the active user, network, domain, schema, and current form data as context
- receive a normalized import result
- merge the imported values into the active schema form
Design Goals
Section titled “Design Goals”- keep credential-source logic out of form pages
- allow one deployment to ship multiple providers side by side
- let projects replace Dhiway-specific services without rewriting the UI flow
- map imported credential data into different schema shapes with minimal code changes
Runtime Flow
Section titled “Runtime Flow”profile-form-page.tsxchecks whether a profile schema is active and whether any wallet provider is configured.- When both conditions are true, the page shows
Import Credentials. WalletImportModallists all registered providers and enables only the configured ones.- The selected provider completes its own verification or authorization flow.
- The provider returns a
WalletImportResultwith normalized data, alias candidates, metadata, and optional raw payload. mergeImportedDataIntoSchema()matches imported values into the active JSON Schema and updates the form state.- The UI shows a success message with mapped and skipped field counts.
Provider Contract
Section titled “Provider Contract”Providers implement the shared WalletProvider contract from engine/wallet/types.ts.
The contract keeps all integrations consistent:
name,label,description: visible catalog metadatacomponent: provider-specific UI and network flowisConfigured(): deploy-time availability checkgetConfigurationHint(): operator-facing message when config is missing
The import result is also standardized:
data: directly mapped values when a provider can supply them confidentlycandidates: expanded alias/value pairs used by the schema mapperrawPayload: original source payload for additional matching and debugging contextmetadata: provider-specific metadata such as issuer or credential identifierssummary: short success text for UI feedback
Registered Providers Today
Section titled “Registered Providers Today”The UI currently registers these providers at startup from src/components/wallet/providers/index.ts:
dhiway-walletdigilocker
This registration happens once in src/main.tsx, so the rest of the app can remain unaware of provider implementations.
Dhiway Wallet Flow
Section titled “Dhiway Wallet Flow”The Dhiway Wallet provider is an example of a credential-wallet integration driven by user identifier verification.
Flow:
- Read the signed-in user’s email and phone number from auth context.
- Let the user choose one available identifier.
- Request a verification code from the wallet service.
- Verify the code and store the returned wallet token.
- Fetch verified credentials for that identifier.
- Let the user choose one credential to import.
- Transform the selected credential into normalized candidates for schema mapping.
Required env:
VITE_VC_WALLET_URLVITE_VC_WALLET_API_KEY
Current service endpoints:
POST /api/v1/auth/request-codePOST /api/v1/auth/verify-codeGET /api/v1/verified-credentials
DigiLocker Flow
Section titled “DigiLocker Flow”The DigiLocker provider is an example of an external credential-pull flow that is not driven by the wallet verification endpoints.
Flow:
- Start an authorization request through the DigiLocker agent service.
- Open the returned URL in a popup.
- Detect the returned code automatically when the popup reaches a redirect bridge page, or let the user paste the code manually.
- Exchange the code through the agent service.
- Transform the returned
credentialSubjectinto import candidates.
Required env:
VITE_AGENT_URLVITE_AGENT_TOKEN
Current service endpoints:
GET /api/v1/discover/digilocker-requestPOST /api/v1/discover/digilocker-auth
Schema-Aware Mapping
Section titled “Schema-Aware Mapping”The key to provider-agnostic import is lib/import-mapping.ts.
It avoids one-off UI code per provider or per schema by:
- flattening nested external payloads into a candidate map
- generating normalized aliases for raw keys
- reading schema-level alias extensions from each property
- coercing string values into numbers when the schema expects numeric types
- reporting skipped fields when no schema property matches
Supported schema extensions:
x-import-aliasesx-import-pathsx-wallet-aliases
These extensions let a schema say that one local property can accept values from many external names such as fullName, full_name, name, or a nested issuer-specific path.
Why This Is Provider-Agnostic
Section titled “Why This Is Provider-Agnostic”The current deployment uses Dhiway Wallet and Dhiway-backed DigiLocker services, but the UI architecture does not depend on those names.
A replacement provider only needs to:
- register itself
- expose its own configuration rules
- return the shared import result shape
That means a project can swap in another wallet, another DigiLocker connector, or another credential broker without rewriting the profile form experience.
Recommended Project Pattern
Section titled “Recommended Project Pattern”For project-specific deployments, treat credential import as a capability layer instead of a vendor feature.
- keep providers behind the registry contract
- keep form mapping in schema metadata, not component conditionals
- keep vendor env and endpoint details isolated to provider clients
- document which providers are default, optional, or deployment-specific