Changelog
Release notes for the @mattrglobal/mobile-credential-holder-react-native package.
10.0.0
Refer to the migration guide for details on how to update your implementation to this major version.
Breaking Changes
Several functions now return a Result
Seven functions that previously resolved a plain value now return a neverthrow Result, so their expected error cases
can be handled without a try/catch. Callers must handle the Result instead of using the resolved value directly.
These functions can still throw, so a try/catch is still required alongside handling the Result. Refer to each
function's @throws annotation for the errors it can throw, and to
RuntimeException may be thrown by any function.
| Function | Previously | Now |
|---|---|---|
deleteCredential | Promise<void> | Promise<Result<void, DeleteCredentialError>> |
destroy | Promise<void> | Promise<Result<void, DestroyError>> |
deleteTrustedVerifierCertificate | Promise<void> | Promise<Result<void, DeleteTrustedVerifierCertificateError>> |
getCredentials | Promise<MobileCredentialMetadata[]> | Promise<Result<MobileCredentialMetadata[], GetCredentialsError>> |
getTrustedIssuerCertificates | Promise<TrustedIssuerCertificate[]> | Promise<Result<TrustedIssuerCertificate[], GetTrustedIssuerCertificatesError>> |
getTrustedVerifierCertificates | Promise<TrustedVerifierCertificate[]> | Promise<Result<TrustedVerifierCertificate[], GetTrustedVerifierCertificatesError>> |
getCurrentProximityPresentationSession | Promise<ProximityPresentationSession | undefined> | Promise<Result<ProximityPresentationSession | undefined, GetCurrentProximityPresentationSessionError>> |
The matching error types are now exported from the package:
DeleteCredentialErrorDestroyErrorDeleteTrustedVerifierCertificateErrorGetCredentialsErrorGetTrustedIssuerCertificatesErrorGetTrustedVerifierCertificatesErrorGetCurrentProximityPresentationSessionError
Before:
const credentials = await Holder.getCredentials();After:
try {
const getCredentialsResult = await Holder.getCredentials();
if (getCredentialsResult.isErr()) {
// Handle error from getCredentialsResult.error
return;
}
const credentials = getCredentialsResult.value;
} catch (error) {
// Handle unexpected thrown errors
}Credential retrieval results are now discriminated unions
The RetrieveCredentialsResponse array items are now isSuccess-discriminated unions instead of a single object with
optional fields. Each item is either a RetrieveCredentialSuccess or RetrieveCredentialFailure, and TypeScript will
enforce which fields are available after narrowing.
Before:
for (const item of result) {
if (item.credentialId) {
console.log(item.credentialId);
} else {
console.log(item.error?.message);
}
}After:
for (const item of result) {
if (item.isSuccess) {
// item is RetrieveCredentialSuccess — credentialId is guaranteed
console.log(item.credentialId);
} else {
// item is RetrieveCredentialFailure — error is guaranteed
console.log(item.error.message);
}
}RetrieveCredentialSuccesshasisSuccess: true,docType, andcredentialId.RetrieveCredentialFailurehasisSuccess: false,docType, anderror.- The
errorfield is no longer optional - it is always present on failure items and never present on success items. - The
credentialIdfield is no longer optional - it is always present on success items and never present on failure items.
doctype renamed to docType
The doctype field has been renamed to docType (camelCase) to align naming across iOS and Android platforms. This
affects credential retrieval result items and OfferedCredential (returned by discoverCredentialOffer). Update all
references from .doctype to .docType.
MobileCredentialAuthenticationOption renamed to DeviceAuthenticationOption
The MobileCredentialAuthenticationOption enum has been renamed to DeviceAuthenticationOption, and the
mobileCredentialAuthenticationOption field of CreateProximityPresentationSessionOptions has been renamed to
deviceAuthenticationOption. This aligns naming with the native holder SDKs, which made the same rename in iOS 6.0.0
and Android 7.0.0. The Signature and Mac values are unchanged.
Neither previous name is exported any more, so update all imports, type references, and the option passed to
createProximityPresentationSession.
Before:
import { MobileCredentialAuthenticationOption } from "@mattrglobal/mobile-credential-holder-react-native";
const result = await Holder.createProximityPresentationSession({
onRequestReceived,
mobileCredentialAuthenticationOption: MobileCredentialAuthenticationOption.Mac,
});After:
import { DeviceAuthenticationOption } from "@mattrglobal/mobile-credential-holder-react-native";
const result = await Holder.createProximityPresentationSession({
onRequestReceived,
deviceAuthenticationOption: DeviceAuthenticationOption.Mac,
});On Android, passing the old mobileCredentialAuthenticationOption key after upgrading fails with an InvalidParams
error rather than being ignored, as described in
Android now rejects unknown argument keys. On iOS the key is ignored and
the default authentication option is used.
DeviceKeyAuthenticationType removed in favour of UserAuthenticationType
The DeviceKeyAuthenticationType enum export has been removed.
- Use
UserAuthenticationTypeinstead. It now carries the same values:None,UserPresence,BiometryAny,BiometryCurrentSet, andDeviceCredential. - Update all references, including the
typefield ofDeviceKeyAuthenticationPolicypassed togenerateDeviceKey,retrieveCredentials, andretrieveCredentialsUsingAuthorizationSession.
Before:
const result = await Holder.generateDeviceKey({
issuer,
audience,
authenticationPolicy: { type: DeviceKeyAuthenticationType.BiometryCurrentSet },
});After:
const result = await Holder.generateDeviceKey({
issuer,
audience,
authenticationPolicy: { type: UserAuthenticationType.BiometryCurrentSet },
});UserAuthenticationType values have changed
UserAuthenticationType is used for the userAuthenticationType field of userAuthenticationConfiguration passed to
initialize.
- It previously carried only
BiometricOnlyandBiometricOrPasscode. - It now carries
None,UserPresence,BiometryAny,BiometryCurrentSet, andDeviceCredential, matching the values used for device key authentication policies. BiometricOnlyis replaced byBiometryCurrentSet.BiometricOrPasscodeis replaced byUserPresence.- The default for
userAuthenticationTypeis nowUserPresence, previouslyBiometricOrPasscode. initializemay now returnUserAuthenticationNotSupportedon Android whenBiometryCurrentSetis combined with auserAuthenticationBehaviorofOnInitialize.
Before:
await Holder.initialize({
userAuthenticationConfiguration: {
userAuthenticationBehavior: UserAuthenticationBehavior.OnDeviceKeyAccess,
userAuthenticationType: UserAuthenticationType.BiometricOrPasscode,
},
});After:
await Holder.initialize({
userAuthenticationConfiguration: {
userAuthenticationBehavior: UserAuthenticationBehavior.OnDeviceKeyAccess,
userAuthenticationType: UserAuthenticationType.UserPresence,
},
});Removed deprecated authentication types
The DeprecatedDeviceKeyAuthenticationType enum (and its BiometricOnly and BiometricOrPasscode values) has been
removed. A device key that was previously associated with a deprecated type is now reported as its modern equivalent:
BiometricOnly→BiometryCurrentSetBiometricOrPasscode→UserPresence
Update any code that references DeprecatedDeviceKeyAuthenticationType to use the corresponding
UserAuthenticationType value.
VerificationResult failure shape changed
On a failed verification, the failure detail has moved from a reason property to failureType, and the
VerificationFailedReason type has been removed. The value shape ({ type, message }) is unchanged.
Before:
if (!credential.verificationResult.verified) {
console.log(credential.verificationResult.reason.type);
}After:
if (!credential.verificationResult.verified) {
console.log(credential.verificationResult.failureType.type);
}Invalid-argument errors now use the InvalidParams error code
Invalid or malformed arguments are now rejected with an InvalidParams error code and a message describing the
offending field, instead of a synchronous Error with a message of the form
Invalid arguments for '<function>' function: .... Update any code that matched on the previous message.
Android now rejects unknown argument keys
Android rejects unrecognized keys in argument objects: any extra or misspelled field that is not part of a function's
documented options fails with an InvalidParams error. iOS ignores unknown keys. Ensure argument objects contain only
documented fields so behavior is consistent across platforms.
OfferedCredential.claims is now optional
claims on OfferedCredential (returned in credentials from discoverCredentialOffer) is now optional and is only
present for offers that contain claim data. This aligns with the
OID4VCI 1.0 specification.
Handle the case where claims is absent rather than assuming an array is always present.
Credentials with empty claims are now rejected
Retrieving or adding a credential whose issuer signed data contains no namespaces, or a namespace with no claims, now
fails with a decoding error instead of producing a credential with empty claims. Android already rejected these
credentials, so behavior is now consistent across both platforms. This guarantees that MobileCredential.claims and
MobileCredentialMetadata.claims are always populated. Handle the error where credentials are retrieved or added.
Pre-authorized issuance now sends the application client_id
Pre-authorized credential issuance flows now pass the application's client_id instead of a default identifier, so the
holder is accurately represented when interacting with issuers. This improves compatibility with issuers applying
stricter controls. Ensure your application has a valid configured client_id and that your issuers recognize it.
Renamed and removed exports
| Export | Change |
|---|---|
SessionStatus | Renamed to SessionStatusErrorType. Also the type of PresentationSessionTerminationError.sessionStatus. |
DateTime | Removed. The validFrom, validUntil, expectedUpdate, and signed fields of ValidityInfo are now typed as Date. |
NativeRetrieveCredentialsResponse | Removed. Use RetrieveCredentialsResponse, or the RetrieveCredentialItem, RetrieveCredentialSuccess, and RetrieveCredentialFailure types. |
MobileCredentialHolderErrorType.ExistingProximityPresentationSessionNotFound | Moved to the new MobileCredentialHolderReactNativeErrorType enum. Update references to MobileCredentialHolderReactNativeErrorType.ExistingProximityPresentationSessionNotFound. |
ProximityPresentationSessionTerminationErrorType.Exception | Removed. Handle unexpected presentation failures with your generic fallback strategy. |
RetrieveCredentialsErrorTypes.UserAuthentication | Removed. Use RetrieveCredentialsErrorTypes.UserAuthenticationFailed. |
RetrieveCredentialsErrorTypes.UserAuthenticationFailed value changed
RetrieveCredentialsErrorTypes.UserAuthenticationFailed now has the value "UserAuthentication", previously
"UserAuthenticationFailed". Code that compares the raw error string rather than the enum member must be updated.
Errors removed from function error types
Two errors are no longer raised and have been removed from the error types they appeared in:
sendOnlinePresentationResponseno longer returnsAuthorizationResponseJWECreationFailed.sendProximityPresentationResponseno longer returnsUserAuthenticationUnrecoverableKey.
Features
SDK Backend support
Added support for an SDK Backend, which ties each SDK and app instance to a MATTR VII tenant. This lets you view details about registered and active app instances directly from your tenant for operational insight, and it establishes a remote management channel that we expect to extend in future releases. It is also what enables Wallet Attestation, described below, which cannot be used without it. On first initialization the SDK registers the app instance with the configured tenant and obtains a license. Subsequent initializations renew the existing license automatically. Network access is required when registration or renewal is performed.
- A new optional
platformConfigurationparameter has been added toinitialize. It accepts:tenantHost: base URL of the MATTR VII tenant (for examplehttps://your-tenant.global).applicationId: identifier of the MATTR VII holder application associated with this SDK.externalReferenceId(optional): a developer-defined identifier used to correlate this app instance with a record in MATTR VII.
- When
platformConfigurationis provided, the SDK registers the app instance with your tenant and enables the SDK Backend. When it is omitted, the SDK skips registration and does not connect to a backend, so capabilities such as Wallet Attestation are unavailable. - The
PlatformConfigurationtype is now exported from the package.
await Holder.initialize({
platformConfiguration: {
tenantHost: "https://your-tenant.global",
applicationId: "00000000",
},
});The SDK Backend is currently optional, but we expect to make it required in an upcoming release, so we recommend configuring it now to prepare. Refer to the SDK Backend guide for more details on how to enable and use this feature.
SDK Backend error handling
Initialization and the majority of public APIs can now surface SDK Backend failures as typed Result errors instead of
throwing them.
initializemay now returnInvalidLicense(the SDK license failed to validate or has expired) orFailedToRegister(registering the app instance with MATTR VII failed).- Both error codes map consistently across iOS and Android.
InvalidLicense may also be returned by the following public APIs when an SDK Backend is configured but a valid license
is not present:
addCredentialgetCredentialgetCredentialsdeleteCredentialgenerateDeviceKeydiscoverCredentialOffercreateAuthorizationSessionretrieveCredentialsretrieveCredentialsUsingAuthorizationSessioncreateOnlinePresentationSessioncreateProximityPresentationSessionsendProximityPresentationResponsegetCurrentProximityPresentationSessionaddTrustedIssuerCertificatesaddTrustedVerifierCertificatesgetTrustedIssuerCertificatesgetTrustedVerifierCertificatesdeleteTrustedIssuerCertificatedeleteTrustedVerifierCertificate
Wallet Attestation
Added support for Wallet Attestation, so you can claim credentials from issuers that restrict issuance to trusted wallet
applications. When an issuer's authorization server advertises attestation-based client authentication, the SDK proves
the application's authenticity automatically before claiming credentials. Wallet Attestation requires an SDK Backend, so
a platformConfiguration must be passed to initialize.
DiscoveredCredentialOffernow exposestokenEndpointAuthMethodsSupported(the client authentication methods supported by both the offer's authorization server and the SDK), along withauthorizationServerIssuerand an optionalnonceEndpoint. ThetokenEndpoint,credentialEndpoint, andmdocIacasUrifields it already returned are now part of the public type.retrieveCredentialsandretrieveCredentialsUsingAuthorizationSessionmay now return:InvalidCredentialOffer: the offer requires attestation but noplatformConfigurationwas provided, or the SDK supports none of the authorization server's advertised client authentication methods.InvalidWalletAttestation: the authorization server rejected the attestation token.
- When attestation fails for an individual credential, that credential's
RetrieveCredentialFailurecarries aninvalidWalletAttestationerror.
Refer to the Wallet Attestation guide for more details on how to enable and use this feature.
Expanded and consistent error types
Many public functions now surface errors as typed error codes that you can handle, where they previously surfaced as unrecognized thrown errors. The same error codes are now raised on both iOS and Android.
The following error codes were previously declared only as per-function string literals and are now members of
MobileCredentialHolderErrorType:
FailedToRetrieveCredentialsFailedToDiscoverCredentialOfferFailedToCreateAuthorizationSessionRedirectUriNotFoundInvalidTransactionCodeWebAuthenticationFailedUnsupportedDeviceKeyAuthenticationPolicyInvalidCredentialOffer
The per-function enums that reference these codes keep the same values:
DiscoverCredentialOfferErrorTypeCreateAuthorizationSessionErrorTypeRetrieveCredentialsErrorTypes
New MobileCredentialHolderErrorType members:
StorageInitialization: storage could not be initialized for the SDK.SdkNotInitialized: the SDK has not been initialized.DeviceKeyGenerationError: a device key could not be generated.DeviceKeyNotDeleted: a device key could not be deleted from storage.InvalidCertificate: a supplied certificate is not valid.ClientMetadataServiceError: verifier client metadata could not be resolved during an online presentation.ResponseModeNotSupported: the authorization request asked for an unsupported response mode.FailedToCreateProximityPresentationSession: a proximity presentation session could not be created.NfcDeviceEngagementNotFound: a proximity session was started withengagementFromNfcbut no NFC device engagement was available.ActivityRequired: an Android activity is required to complete the operation.InvalidDeviceKeyAuthenticationPolicy: the supplied device key authentication policy is not valid.DeviceKeyAuthenticationPolicyChangedException: the authentication policy of an existing device key has changed.UserAuthenticationInvalidatedByBiometricEnrollment: the device key was invalidated because the biometrics enrolled on the device changed.UserAuthenticationNotSupported: the requested user authentication configuration is not supported on this device.MACAuthenticationUnavailableForAuthenticationPolicy: MAC authentication cannot be used with the credential's authentication policy.CalledFromAppExtension: an API that is unavailable in app extensions was called from an iOS app extension.OperationFailed: the operation failed for a platform-specific reason described in the error message.RuntimeException: an unexpected or unrecoverable failure in the SDK.
New ProximityPresentationSessionErrorType members:
ResponseNotCreatedResponseEncryptionFailedSessionDecryptionPresentationNotCreated
The functions whose existing error types were extended are:
initializeaddCredentialgetCredentialgenerateDeviceKeydiscoverCredentialOffercreateAuthorizationSessionretrieveCredentialsretrieveCredentialsUsingAuthorizationSessioncreateOnlinePresentationSessionsendOnlinePresentationResponsecreateProximityPresentationSessionsendProximityPresentationResponse
The seven functions that gained an error type for the first time are listed in
Several functions now return a Result.
RuntimeException may be thrown by any function
RuntimeException is the catch-all for an unexpected or unrecoverable failure in the SDK. Because any function may
throw it, it is not listed in each function's expected Result error type. Handle it with your generic fallback
strategy and report it to MATTR.
Bug fixes
Security fixes
- Authorization request objects are now validated against their
iat,exp, andnbfclaims on Android. The SDK previously performed no temporal validation, so a request object with anexpin the past could be replayed, and aniatin the future was accepted. - The OID4VP
stateparameter is now size limited on Android during online presentation. Arbitrarily large values were previously accepted and echoed back. - The Digital Credentials API origin on Android now uses an unpadded base64 encoded SHA-256 of the app signing
certificate (
android:apk-key-hash:<base64SHA256>) instead of hex, matching MATTR VII and reference wallet implementations. Verification previously failed because of the mismatch.
Proximity and NFC presentation
- Fixed an issue on Android where NFC device engagement via negotiated handover could get stuck in an infinite loop on certain Samsung devices. The SDK now keeps the HCE session alive through internal activity transitions, guards against re-entrant engagement, and cancels stuck engagements when the NFC field is lost prematurely.
- Improved UI stability on Android when the app is launched by an NFC interaction. The system no longer prompts the user to choose an application in most cases, addressing the multiple system prompts noted in the 9.0.0 known issues.
- Fixed an issue on iOS where receiving a session status code, such as a session termination, emitted a spurious request-received callback and raised a redundant session terminated error. The session now terminates cleanly through the termination handler.
- Hardened proximity presentation message handling on iOS. Empty BLE data chunks received during message reassembly are now discarded, preventing a crash when a peer sends malformed data.
Credential claiming
- Fixed an issue on iOS where credential issuance web authentication was canceled when the app moved to the background. The authorization can now complete after returning to the app.
- Fixed an issue on Android where credential offers were rejected if the authorization server metadata was missing
token_endpoint_auth_methods_supported. - Fixed an issue on Android where OID4VCI metadata URIs were calculated incorrectly.
- Fixed a crash on Android where oversized credential fields could exhaust memory during pre-authorized issuance. Such credentials are now rejected before they can exhaust memory.
Online presentation
- Fixed a crash on Android during online presentation when the
x5cheader was stripped from a validly signed request object JWT. The malformed request is now rejected gracefully. - Fixed an issue on Android where a malformed authorization request JWS raised an unexpected error.
Storage, initialization, and authentication
- Fixed an issue on iOS where an unretrievable database encryption key caused a
StorageInitializationerror after certain app lifecycle transitions. - Fixed an issue on iOS where switching an existing instance to a different app group did not remove the previous app group's data. The previous app group's data is now cleared when the app group is switched.
- Error messages are now specific when a key protected by
BiometryCurrentSetis invalidated by biometric re-enrollment on iOS. Signing with such a key previously surfaced an opaqueCryptoTokenKiterror.
Digital Credentials API
- Fixed an issue on Android where requesting only an
age_over_xxattribute during a Digital Credentials API flow showed no result on the consent screen instead of displaying the requested attribute before sharing. - Fixed an issue on Android where a Digital Credentials API presentation required every requested claim to be available. A credential that matches any single requested claim is now offered.
- Fixed an issue on iOS where credentials added in the main app could be missing when a verifier requested them through the Digital Credentials API.
Known Issues
- If your app includes its own iOS app extension, the internal storage location for iOS app extension logs has changed.
Logs are still retrieved with the same
getCurrentLogFilePathcall andappGroupoption, so no code changes are required, but any app extension logs written before upgrading, up to the 48 hour retention window, are no longer accessible after the upgrade. The location for main SDK logs is unchanged.
9.0.5
Bug fixes
- Fixed an issue on iOS where restoring an app from a backup or moving it to a new device left the SDK unusable, with
initialize always throwing
StorageInitialization. The SDK now clears the unreadable storage and initializes cleanly. Credentials held before the restore must be reissued. - Fixed an issue on Android where instance IDs longer than 64 characters would prevent DCM from registering credentials.
- Fixed an issue on Android where OID4VCI metadata URIs were calculated incorrectly.
- Fixed an issue on Android where credential offers were rejected if the authorization server metadata was missing
token_endpoint_auth_methods_supported.
9.0.4
Bug fixes
-
Fixed an issue on Android where the SDK could crash if DCM configuration cleanup failed. Cleanup errors are now caught and logged, allowing the host app to continue safely.
-
On iOS the SDK now recovers automatically from a storage key mismatch without data loss. A stored storage key could become stale for a number of reasons, leaving the SDK unable to initialize against existing credential data. This was most commonly observed during background prewarming, where the SDK could launch before the device’s first unlock and be unable to read existing keychain items. On initialization, the SDK now verifies the active storage key against an on-disk probe and, if the recorded key is stale, locates the correct key among the available keychain candidates and repairs the stored reference. If the probe cannot be read because of filesystem protection,
StorageInitializedInBackgroundis thrown.Recovery sequence: the active storage key is verified by attempting to decrypt an encrypted on-disk probe. If the recorded key is stale, the SDK enumerates all available keychain candidates, identifies the one that successfully decrypts the probe, updates the stored key, and removes the stale entry.
9.0.3
Bug fixes
- Added
Noneas aDeviceKeyAuthenticationTypeoption. This allows credentials to be generated or retrieved with no user authentication requirement, even when the SDK is initialized withuserAuthenticationBehaviorset toAlwaysorOnDeviceKeyAccess. Pass{ authenticationPolicy: { type: "None" } }toretrieveCredentials,retrieveCredentialsUsingAuthorizationSession, orgenerateDeviceKeyto opt out of authentication for a specific device key.
9.0.2
Bug fixes
This release fixes the following iOS issues:
- Fixed an issue where the SDK did not use the OID4VCI nonce endpoint during credential issuance when required by the
issuer. The SDK now automatically fetches an issuer-provided nonce from
nonceEndpoint(when it is advertised in the issuer metadata) and includes it in the device key proof-of-possession JWT, improving compliance with the OID4VCI specification. - Fixed an issue where calling
discoverCredentialOfferwould fail when credential metadata did not include any claims. Theclaimsfield is now treated as optional and defaults to an empty array when absent. - Fixed an issue where SDK initialization could fail on iOS devices due to inconsistent storage states, such as orphaned keychain keys after an app reinstall or transferred files without keys after device migration. The SDK now performs a preflight check and automatically recovers from these states.
- Fixed an issue where SDK storage files and directories could be included in iOS device backups, resulting in encrypted data being backed up without the keys required to restore it. These files are now excluded from iCloud and local backups.
- Fixed an issue where calling the
destroyfunction did not fully remove persisted data on iOS devices. It now also deletes the database encryption key and storage key ID from the keychain, preventing orphaned keychain entries.
9.0.1
Bug Fixes
- Fixed an issue where native binaries were not included in the builds published to NPM.
9.0.0
Breaking Changes
OpenID4VCI Version 1.0 Alignment
The SDK now aligns with the finalized OpenID for Verifiable Credential Issuance (OID4VCI) v1.0 specification, upgrading from draft-12.
- The OfferedCredential type (in
credentialsfromdiscoverCredentialOffer(..)) now includes a mandatorycredentialConfigurationIdproperty. - Compatibility with issuers implementing earlier OID4VCI draft versions is no longer guaranteed.
Simplified status check parameter
Replaced skipStatusCheck with fetchUpdatedStatusList to improve readability and reduce integration confusion:
true(default): Fetch the latest revocation status list from the server.false: Use cached revocation status (if valid).
New error types for the initialize method
The initialize method can now return new error types to provide more specific feedback on initialization failures:
StorageInitializedInBackgroundSdkInitializedInvalidInstanceID
New error type in ProximityPresentationSessionTerminationErrorType
New Exception value was added to ProximityPresentationSessionTerminationErrorType. This is a fallback when an
unexpected issue occurs during presentation.
Package path change
The package path for global.mattr.mobilecredential.common has been updated to global.mattr.mobilecredential.holder.
Please ensure that you update your imports accordingly to avoid any issues with module resolution.
Xcode / Toolchain dependencies
The underlying iOS SDK is built with Xcode 26.0.0. Builds will fail on earlier toolchains (e.g. Xcode 16.4) and CI environments must be upgraded.
Features
Digital Credentials API (DC API) support
Added support for iOS’s Digital Credentials API, as defined in ISO/IEC 18013-7 Annex C (for iOS) and D (for Android). This update allows wallet apps using the Holder SDK to register stored credentials with the system, enabling them to appear in the DC API’s selector UI when a verifier requests credentials.
- A new optional
dcConfigurationparameter has been added toinitializewhich controls DC API behavior. You can set different options for iOS and Android. - When enabled, the SDK will automatically register credentials with the DC API after initialization and whenever credentials are added or removed. This means that credentials stored in the Holder SDK will be available for selection in the DC API without requiring additional integration work.
Logging in iOS app extensions
- The SDK may now generate logs in an iOS app extension.
getCurrentLogFilenow includes an optionalappGroupparameter. UseappGroupif you want to retrieve logs in the extension. On other platforms,getCurrentLogFileignoresappGroup.
mDoc Reader Authentication
Added support for mDoc Reader authentication as defined in ISO/IEC 18013-5:2021. The SDK can now be used to inspect the verifier authentication result and enable the user to decide whether to share credentials with an unauthenticated verifier.
- Introduced a new
VerifierAuthenticationResulttype which represents the mDoc Reader Authentication result. - Introduced a new
verifierAuthenticationResultproperty of typeVerifierAuthenticationResultinMobileCredentialRequest.- This can result in a
"trusted","untrusted", or"unsigned"request.
- This can result in a
- Introduced a new
VerifierInfotype which represents information regarding the root certificate used to verify the request. - Introduced a new
VerifierAuthenticationErrorwhich represents the specific authentication error encountered during verification. - Introduced a new
VerifierAuthenticationErrorTypewhich represents the string literal that can be returned in thetypefield ofVerifierAuthenticationError.
Device key authentication
Device key authentication offers fine-grained control over how each credential is protected and accessed on a user’s device. You can now specify a per-credential authentication policy that defines what user authentication (such as device credentials or biometrics) is required to claim and access a credential.
You can set authentication policy using three methods:
generateDeviceKeyretrieveCredentialsretrieveCredentialsUsingAuthorizationSession
All three methods generate device keys, with the latter two binding credentials keys. To set authentication policy, use
the authenticationPolicy property as shown below:
const deviceKeyResult = await Holder.generateDeviceKey({
issuer,
audience,
authenticationPolicy: {
type: DeviceKeyAuthenticationType.BiometryCurrentSet,
},
});generateDeviceKey will store the key with the strictest authentication policy, BiometryCurrentSet. Any access to the
key now requires biometric authentication. It will only allow the current set of biometrics too; changing biometric
settings will invalidate the key.
The four authentication types are as follows, in order of strength:
DeviceCredential: As long as the user has unlocked their phone, they have access to the key. Any authentication method allowedUserPresence: Requires PIN, fingerprint, etc. on each access to the key. Any authentication method allowed.BiometryAny: Key is accessible only with biometric authentication, but changing or removing biometric settings is allowed.BiometryCurrentSet: Key is accessible only with the current set of biometrics. Changing or removing a biometric will invalidate the key.
NFC proximity presentation support
The SDK now supports NFC device engagement for Android devices. This enables starting a proximity presentation session via the NFC channel. A session can now begin when the user taps their device on an NFC-enabled verifier terminal.
The very first step is to add this intent filter to the AndroidManifest.xml of your React Native app:
<intent-filter>
<action android:name="global.mattr.mobilecredential.holder.NFC_RECEIVER_ACTIVITY" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>Then listen for NFC device engagement using setDeviceEngagementListener:
await Holder.setDeviceEngagementListener((error) => {
if (error) {
handleError(error);
return;
}
// no error - can proceed to next step
});Once the device engagement callback is invoked without error, start the presentation with engagementFromNfc set to
true:
await Holder.createProximityPresentationSession({
...otherOptions,
engagementFromNfc: true,
});The SDK will invoke the listener upon successful NFC engagement, or if there was an error. If error is undefined,
engagement was successful. The SDK has the device engagement information ready to go. You just need to start the
presentation using engagementFromNfc: true.
Four new methods support NFC presentations:
setDeviceEngagementListener- adds or replace the current listener callback.removeDeviceEngagementListener- removes the listener, if already set.setNfcConfigurationandgetNfcConfiguration- update or inspect settings related to NFC.
At this time, device engagement works while the app is in the foreground or background. Cold starts (when app is not running) are not currently supported. To start a presentation from NFC, users will first need to open your app, and then scan the verifier NFC's tag.
Status Lists Draft 14 Support
The SDK now supports the Token Status List Draft 14 specification while maintaining existing support for Draft 3.
- Added support for the
application/statuslist+cwtcontent type header as defined in Section 8.2 of the specification, while maintaining support for the existingmattr-statuslist+cwttype. - Added support for the updated status list URL format where status lists are represented as an array of URI strings rather than an array of objects.
- The SDK respects rate limit response headers returned with HTTP 429 responses from status list endpoints, with a configurable default delay for rate-limited requests.
COSE algorithm updates
Updated COSE algorithms (as per RFC 9864) strengthen cryptographic compatibility and ensure continued compliance with evolving standards.
Known Issues
- Some Samsung Android devices may display multiple system prompts when initiating an NFC credential sharing interaction if several installed apps can handle NFC intents. In these cases, the device may first show a “Select an app to use” dialog (e.g., Wallet vs. embedded tag handler) followed shortly by a “Choose an action” dialog from other NFC-capable apps (e.g., tag readers or transit apps). This behavior appears to be device- and firmware-specific and may interrupt the expected automatic credential sharing flow.
8.1.3
Bug fixes
iOS Platform
- Improved early iOS app launch handling during SDK initialization. The SDK now probes Keychain accessibility before initialization proceeds, ensuring the storageKeyID can be loaded reliably before storage is accessed. This enhances protection against prewarming scenarios where Keychain items may be temporarily unavailable, reducing the likelihood of inconsistent storage state or unrecoverable initialization failures.
- Resolved an issue that caused a crash when decoding
DiscoveredCredentialOfferon devices running iOS 17.0 or earlier. - The SDK now supports ESP256, ESP384, and ESP512 signature algorithms, expanding compatibility with a broader range of ESP-based cryptographic operations.
8.1.2
Bug fixes
Android Platform
- Resolved an issue that prevented retrieving credentials when a
Branding.namevalue was not set.
8.1.1
Bug fixes
iOS Platform
- Resolved an issue where calls to
retrieveCredentialsUsingAuthorizationSessionwould fail on iOS devices running iOS 17.0 or earlier.
8.1.0
OID4VCI manual redirect support
This enhancement allows applications to implement the OpenID4VCI issuance workflow within embedded WebViews while maintaining full control over the redirect flow.
Applications can now:
- Call the new
createAuthorizationSessionmethod to initiate the flow. This returns anAuthorizationSessionobject containing both theauthorizeUrlandcodeVerifierproperties. - Load the returned
authorizeUrlin a WebView to handle user authentication and consent. - After successful authentication, capture the redirect using the configured
redirectUri, then extract the authorization code from the returned URL. - Complete the issuance workflow by calling the new
retrieveCredentialsUsingAuthorizationSessionmethod, passing in theAuthorizationSessionand extracted authorization code.
Bug fixes
- Remove usage of
constfrom enums:UserAuthenticationBehaviorandUserAuthenticationType
iOS Platform
- Fixed an issue where the passcode fallback button was not displayed when biometric authentication failed and
UserAuthenticationTypewas set to.biometricOrPasscode. - Fixed an issue where calling
addCredentialwith a credential that could not be verified against any stored trusted issuer certificate incorrectly threwAddMobileCredentialError.certificateNotFoundinstead ofAddMobileCredentialError.invalidCredential.
Android Platform
- Fixed an issue where closing the embedded browser during the OpenID4VCI authorization flow caused
retrieveCredentialsto hang indefinitely.
8.0.0
Breaking changes
- The React Native supported versions for the SDK is now 0.78.x or higher, including React Native’s New Architecture.
Spelling standardization change (UK → US English)
The following changes reflect the update of the SDK's spelling convention from UK English to US English.
- Methods:
- Renamed the
initialisefunction toinitialize. - Renamed the
deinitialisefunction todeinitialize.
- Renamed the
- Errors:
- Renamed
MobileCredentialHolderError.AuthenticationCancelledtoMobileCredentialHolderError.AuthenticationCanceled. - Renamed
MobileCredentialHolderError.InvalidAuthorisationRequestUritoMobileCredentialHolderError.InvalidAuthorizationRequestUri. - Renamed
MobileCredentialHolderError.InvalidAuthorisationRequestVerifiedByCertificatetoMobileCredentialHolderError.InvalidAuthorizationRequestVerifiedByCertificate. - Renamed
MobileCredentialHolderError.InvalidAuthorisationRequestVerifiedByDomaintoMobileCredentialHolderError.InvalidAuthorizationRequestVerifiedByDomain.
- Renamed
Error handling consolidation
- The
getCredentialmethod was updated as follows:- Added a new verification failure reason
MobileCredentialVerificationFailureType.TrustedIssuerCertificateNotFoundwhen the credential cannot be verified due to missing a matched trusted issuer certificate.
- Added a new verification failure reason
Features
-
Added a
msoHashto theMobileCredentialandMobileCredentialMetadatatypes. This property represents a hashed mobile security object, defined in ISO/IEC 18013-5:2021. Note that this property is distinct from the id property and should not be used in thegetCredentialmethod. -
iOS Platform
- The SDK now includes a check for empty CBOR arrays. Previously the SDK allowed credentials with an empty
IssuerNamespacesfield, but according to the Concise Data Definition Language (CDDL) specification defined in ISO/IEC 18013-5, this field must contain at least one entry. This update enforces that requirement, improving interoperability and ensuring issued credentials are standards-compliant.
- The SDK now includes a check for empty CBOR arrays. Previously the SDK allowed credentials with an empty
7.0.0
Breaking changes
OID4VCI Pre-authorized Code flow support
The SDK now supports credential claiming using the OID4VCI Pre-Authorized Code Flow. Accordingly, the following changes have been introduced:
Method Signatures:
- The
retrieveCredentialsmethod now accepts:- The original offer URL as a
String, instead of the previousCredentialOfferResponsetype for thecredentialOfferparameter - An optional
transactionCode - The
autoTrustMobileIacaandredirectUriparameters are now set in theinitialisemethod, whereas previously they were parameters ofretrieveCredentials.
- The original offer URL as a
- The following properties no longer need to be exposed in the reponse of
discoverCredentialOfferand are now managed interally to the SDK:authorizeEndpoint,tokenEndpoint,credentialEndpoint,mdocIacasUri
- New repsonse parameters added to
discoverCredentialOffer:TransactionCodestruct
User authentication configuration
The initialise method now allows configuring how biometric authentication is performed. To allow this the following
changes were introduced:
- Introduced a new
UserAuthenticationConfigurationobject:UserAuthenticationConfiguration.userAuthenticationBehaviorsupports the following options:UserAuthenticationBehavior.Alwaysrequires user authentication for all supported operationsUserAuthenticationBehavior.Noneno user authentication is requiredUserAuthenticationBehavior.OnDeviceKeyAccessrequires user authentication when presenting or issuing a credentialUserAuthenticationBehavior.OnInitialiserequires user authentication when initialising the SDK
UserAuthenticationConfiguration.userAuthenticationTypeis iOS only and supports the following options:UserAuthenticationType.BiometricOnlyonly biometric authentication is allowedUserAuthenticationType.BiometricOrPasscodeauthentication with either biometrics or device passcode
- Replaced the
userAuthRequiredOnInitialiseboolean parameter in theinitialisemethod withuserAuthenticationConfigurationof typeUserAuthenticationConfiguration. - Renamed the
MobileCredentialHolderErrorType.UserAuthenticationOnInitChangederror type toMobileCredentialHolderErrorType.UserAuthenticationConfigurationChanged. - Renamed
CredentialIssuanceOptionstoCredentialIssuanceConfiguration
Error handling consolidation
In order to provide a more cohesive and manageable error handling in the OID4VCI flow, we have consolidated some error cases into broader ones. This change aims to make it easier for developers to handle errors consistently. Below is a summary of the changes:
discoverCredentialOfferno longer throws the following errors:DiscoverCredentialOfferErrorType.CredentialOfferNotFoundDiscoverCredentialOfferErrorType.SupportedCredentialsNotFoundDiscoverCredentialOfferErrorType.CredentialOfferNotInCredentialIssuerMetadataDiscoverCredentialOfferErrorType.IssuerMetadataServiceError
- Instead, these errors were consolidated into:
DiscoverCredentialOfferErrorType.FailedToDiscoverCredentialOffer
**To see the full list of errors that discoverCredentialOffer may throw, refer to this method in the
SDK documentation.
**
retrieveCredentialsno longer throws the following errors:RetrieveCredentialsErrorTypes.AuthCodeNotFoundRetrieveCredentialsErrorTypes.AuthenticationFailedRetrieveCredentialsErrorTypes.CertificateNotFoundRetrieveCredentialsErrorTypes.DeviceKeyGenerationErrorRetrieveCredentialsErrorTypes.GenerateAuthorisationUrlFailed
- Instead, these errors have been added:
RetrieveCredentialsErrorTypes.RedirectUriNotFoundRetrieveCredentialsErrorTypes.InvalidTransactionCodeRetrieveCredentialsErrorTypes.WebAuthenticationFailedRetrieveCredentialsErrorTypes.FailedToDiscoverCredentialOffer
Enhancements
- Introduced support for future dated credentials. The
addCredentialmethod can now be used to add credentials with a future validity period to the storage. - [iOS] The SDK's storage data protection class was changed from C (Protected Until First User Authentication) to B (Protected Unless Open). See Apple Platform Security forum for details.
- The SDK no longer checks the signature algorithm when adding verifier certificates. This aligns with ISO/IEC 18013-5:2021, which does not specify required algorithms for reader root certificates.
Bug fixes
- Fixed an issue where special characters in credential offers were escaped twice.
- Resolved a potential crash when establishing a BLE connection.
- Fixed an issue where the browser would retain focus after authenticating during credential retrieval via OpenID4VCI.
- Fixed validation for ES384 and ES512 signatures.
- Enabled using RSA as a digital signature algorithm for Reader Authentication root certificates.
6.0.0
Features
First GA release as a standalone SDK.
How would you rate this page?