Request or download the MATTR Pi SDK Trial License Agreement and the MATTR Customer Agreement and review these terms.
| Technology | Version |
|---|---|
| Xcode | 26 or higher |
| iOS | 15(*) or higher |
| iPhone | iPhone 6S or higher |
| Technology | Version |
|---|---|
| Android Gradle Plugin | 8.3.0 |
| Gradle | 8.3 |
| Kotlin | 1.9.0 |
| JDK | 17 |
| Android min API level | 24 |
| Android target API level | 34 |
| Technology | Version |
|---|---|
| Node | v18 or higher |
| React Native | 0.83.x or higher |
SDK was tested with react-native 0.83.0, and 0.86.0.
Refer to our SDK Docs landing page for step-by-step instructions to gain access to any of our SDKs.
Please reach out in case you need any assistance.
yarn add @mattrglobal/mobile-credential-holder-react-native
Linking the package manually is not required from React Native 0.60 and higher that supports Autolinking.
The SDK relies on the following peer dependencies:
Install the pods (via Cocoapods) to complete the linking.
npx pod-install ios
The precompiled MATTR Mobile Credential Holder Android Native SDK is provided in the published NPM package.
To bundle the native libraries, append the following changes to the android/build.gradle script:
allprojects {
repositories {
…
google()
+ maven {
+ url = "$rootDir/../node_modules/@mattrglobal/mobile-credential-holder-react-native/android/frameworks"
+ }
}
}
Add the following activity to your app's android manifest:
<application>
...
+ <activity
+ android:name="global.mattr.mobilecredential.common.webcallback.WebCallbackActivity"
+ android:exported="true"
+ android:label="@string/web_callback_activity_label" >
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+ <data android:scheme="${mattrScheme}"
+ android:host="${mattrDomain}" />
+ </intent-filter>
+ </activity>
...
</application>
This configuration allows your Android app to receive authentication results from the browser. The specified values are used to construct the URI that the SDK will use to redirect the user back to your app after they complete authentication with the issuer:
mattrScheme : Can be any path that is handled by your application and registered with the issuer.mattrDomain : Can be any path, however our best practice recommendation is to configure this to be credentials, as
the standard format for the redirect URI is {redirect.scheme}://credentials/callback.The combination of these values ({mattrScheme}://{mattrDomain}/*) must exactly match a redirect URI that has been
whitelisted for the OAuth client used to authenticate the holder. This is required for the SDK to successfully retrieve
credentials.
This SDK can be used in the same application with version 9.0.0 of the React Native mDocs Verifier SDK (
mobile-credential-verifier-react-native).
The SDK distinguishes between expected and unexpected errors to help you write clearer and more predictable code.
Expected errors are part of the normal operation of a function. In these cases, the SDK function will be wrapped in
a Result object from the neverthrow library, with
an explicit error type you can handle programmatically. Some functions do not have expected failure modes. When that’s
the case, their return type will not be wrapped in a Result object. Although this pattern is more verbose, it
encourages the handling of possible errors and reserves throwing exceptions for truly exceptional situations.
Unexpected errors represent bugs, SDK misuse, or system-level failures. In these cases the SDK will throw an exception which results in a rejected promise. Because the root cause is unknown or unrecoverable, we recommend handling them with a generic fallback strategy (e.g., showing an error screen or logging the issue) appropriate to your app’s context.
This separation ensures you know which errors to handle explicitly and which indicate deeper issues that need broader handling.
Some unexpected errors are not specific to a single function and are therefore not listed in each function's expected
Result error type:
RuntimeException — the catch-all for an unexpected or unrecoverable failure in the native SDK. Any function may
throw it, so it is not enumerated per-function. If you encounter it, handle it with your generic fallback strategy and
report it to MATTR.import { retrieveCredentials } from "@mattrglobal/mobile-credential-holder-react-native";
const retrieveCredentialsResult = await retrieveCredentials( ... );
if (retrieveCredentialsResult.isErr()) {
// Handle error from retrieveCredentialsResult.error
return;
}
const response = retrieveCredentialsResult.value;
If you encounter issues while using the SDK, enabling Native SDK logging can help diagnose problems. You can enable logging during SDK initialization as shown below:
await initialize({
loggerConfiguration: {
logLevel: LogLevel.Verbose,
callbackLogLevel: LogLevel.Verbose,
callback: ({ logLevel, tag, message }) => {
logger.debug(`[${logLevel}][${tag}]: ${message}`);
},
},
});
Refer to the migration guide for details on how to update your implementation to this major version.
ResultSeven 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:
DeleteCredentialErrorDestroyErrorDeleteTrustedVerifierCertificateErrorGetCredentialsErrorGetTrustedIssuerCertificatesErrorGetTrustedVerifierCertificatesErrorGetCurrentProximityPresentationSessionErrorBefore:
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
}
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);
}
}
RetrieveCredentialSuccess has isSuccess: true, docType, and credentialId.RetrieveCredentialFailure has isSuccess: false, docType, and error.error field is no longer optional - it is always present on failure items and never present on success items.credentialId field is no longer optional - it is always present on success items and never present on failure
items.doctype renamed to docTypeThe 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 DeviceAuthenticationOptionThe 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 UserAuthenticationTypeThe DeviceKeyAuthenticationType enum export has been removed.
UserAuthenticationType instead. It now carries the same values: None, UserPresence, BiometryAny,
BiometryCurrentSet, and DeviceCredential.type field of DeviceKeyAuthenticationPolicy passed to generateDeviceKey,
retrieveCredentials, and retrieveCredentialsUsingAuthorizationSession.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 changedUserAuthenticationType is used for the userAuthenticationType field of userAuthenticationConfiguration passed to
initialize.
BiometricOnly and BiometricOrPasscode.None, UserPresence, BiometryAny, BiometryCurrentSet, and DeviceCredential, matching the
values used for device key authentication policies.BiometricOnly is replaced by BiometryCurrentSet.BiometricOrPasscode is replaced by UserPresence.userAuthenticationType is now UserPresence, previously BiometricOrPasscode.initialize may now return UserAuthenticationNotSupported on Android when BiometryCurrentSet is combined with a
userAuthenticationBehavior of OnInitialize.Before:
await Holder.initialize({
userAuthenticationConfiguration: {
userAuthenticationBehavior: UserAuthenticationBehavior.OnDeviceKeyAccess,
userAuthenticationType: UserAuthenticationType.BiometricOrPasscode,
},
});
After:
await Holder.initialize({
userAuthenticationConfiguration: {
userAuthenticationBehavior: UserAuthenticationBehavior.OnDeviceKeyAccess,
userAuthenticationType: UserAuthenticationType.UserPresence,
},
});
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 → UserPresenceUpdate any code that references DeprecatedDeviceKeyAuthenticationType to use the corresponding
UserAuthenticationType value.
VerificationResult failure shape changedOn 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);
}
InvalidParams error codeInvalid 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 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 optionalclaims 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.
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.
client_idPre-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.
| 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 changedRetrieveCredentialsErrorTypes.UserAuthenticationFailed now has the value "UserAuthentication", previously
"UserAuthenticationFailed". Code that compares the raw error string rather than the enum member must be updated.
Two errors are no longer raised and have been removed from the error types they appeared in:
sendOnlinePresentationResponse no longer returns AuthorizationResponseJWECreationFailed.sendProximityPresentationResponse no longer returns UserAuthenticationUnrecoverableKey.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.
platformConfiguration parameter has been added to initialize. It accepts:tenantHost: base URL of the MATTR VII tenant (for example https://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.platformConfiguration is 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.PlatformConfiguration type 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.
Initialization and the majority of public APIs can now surface SDK Backend failures as typed Result errors instead of
throwing them.
initialize may now return InvalidLicense (the SDK license failed to validate or has expired) or FailedToRegister
(registering the app instance with MATTR VII failed).InvalidLicense may also be returned by the following public APIs when an SDK Backend is configured but a valid license
is not present:
addCredentialgetCredentialgetCredentialsdeleteCredentialgenerateDeviceKeydiscoverCredentialOffercreateAuthorizationSessionretrieveCredentialsretrieveCredentialsUsingAuthorizationSessioncreateOnlinePresentationSessioncreateProximityPresentationSessionsendProximityPresentationResponsegetCurrentProximityPresentationSessionaddTrustedIssuerCertificatesaddTrustedVerifierCertificatesgetTrustedIssuerCertificatesgetTrustedVerifierCertificatesdeleteTrustedIssuerCertificatedeleteTrustedVerifierCertificateAdded 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.
DiscoveredCredentialOffer now exposes tokenEndpointAuthMethodsSupported (the client authentication methods
supported by both the offer's authorization server and the SDK), along with authorizationServerIssuer and an
optional nonceEndpoint. The tokenEndpoint, credentialEndpoint, and mdocIacasUri fields it already returned are
now part of the public type.retrieveCredentials and retrieveCredentialsUsingAuthorizationSession may now return:InvalidCredentialOffer: the offer requires attestation but no platformConfiguration was provided, or the SDK
supports none of the authorization server's advertised client authentication methods.InvalidWalletAttestation: the authorization server rejected the attestation token.RetrieveCredentialFailure carries an
invalidWalletAttestation error.Refer to the Wallet Attestation guide for more details on how to enable and use this feature.
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:
FailedToRetrieveCredentialsFailedToDiscoverCredentialOfferFailedToCreateAuthorizationSessionRedirectUriNotFoundInvalidTransactionCodeWebAuthenticationFailedUnsupportedDeviceKeyAuthenticationPolicyInvalidCredentialOfferThe per-function enums that reference these codes keep the same values:
DiscoverCredentialOfferErrorTypeCreateAuthorizationSessionErrorTypeRetrieveCredentialsErrorTypesNew 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 with engagementFromNfc but 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:
ResponseNotCreatedResponseEncryptionFailedSessionDecryptionPresentationNotCreatedThe functions whose existing error types were extended are:
initializeaddCredentialgetCredentialgenerateDeviceKeydiscoverCredentialOffercreateAuthorizationSessionretrieveCredentialsretrieveCredentialsUsingAuthorizationSessioncreateOnlinePresentationSessionsendOnlinePresentationResponsecreateProximityPresentationSessionsendProximityPresentationResponseThe 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 functionRuntimeException 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.
iat, exp, and nbf claims on Android. The SDK
previously performed no temporal validation, so a request object with an exp in the past could be replayed, and an
iat in the future was accepted.state parameter is now size limited on Android during online presentation. Arbitrarily large values were
previously accepted and echoed back.android:apk-key-hash:<base64SHA256>) instead of hex, matching MATTR VII and reference wallet
implementations. Verification previously failed because of the mismatch.token_endpoint_auth_methods_supported.x5c header was stripped from a validly signed request
object JWT. The malformed request is now rejected gracefully.StorageInitialization error after
certain app lifecycle transitions.BiometryCurrentSet is invalidated by biometric re-enrollment
on iOS. Signing with such a key previously surfaced an opaque CryptoTokenKit error.age_over_xx attribute during a Digital Credentials API flow
showed no result on the consent screen instead of displaying the requested attribute before sharing.getCurrentLogFilePath call and appGroup option, 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.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,
StorageInitializedInBackground is 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.
None as a DeviceKeyAuthenticationType option. This allows credentials to be generated or retrieved with no
user authentication requirement, even when the SDK is initialized with userAuthenticationBehavior set to Always or
OnDeviceKeyAccess. Pass { authenticationPolicy: { type: "None" } } to retrieveCredentials,
retrieveCredentialsUsingAuthorizationSession, or generateDeviceKey to opt out of authentication for a specific
device key.This release fixes the following iOS issues:
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.discoverCredentialOffer would fail when credential metadata did not include any claims.
The claims field is now treated as optional and defaults to an empty array when absent.destroy function 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.The SDK now aligns with the finalized OpenID for Verifiable Credential Issuance (OID4VCI) v1.0 specification, upgrading from draft-12.
credentials from discoverCredentialOffer(..)) now includes a mandatory
credentialConfigurationId property.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).The initialize method can now return new error types to provide more specific feedback on initialization failures:
StorageInitializedInBackgroundSdkInitializedInvalidInstanceIDProximityPresentationSessionTerminationErrorTypeNew Exception value was added to ProximityPresentationSessionTerminationErrorType. This is a fallback when an
unexpected issue occurs during presentation.
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.
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.
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.
dcConfiguration parameter has been added to initialize which controls DC API behavior. You can set
different options for iOS and Android.getCurrentLogFile now includes an optional appGroup
parameter. Use appGroup if you want to retrieve logs in the extension. On other platforms, getCurrentLogFile
ignores appGroup.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.
VerifierAuthenticationResult type which represents the mDoc Reader Authentication result.verifierAuthenticationResult property of type VerifierAuthenticationResult in
MobileCredentialRequest."trusted", "untrusted", or "unsigned" request.VerifierInfo type which represents information regarding the root certificate used to verify the
request.VerifierAuthenticationError which represents the specific authentication error encountered during
verification.VerifierAuthenticationErrorType which represents the string literal that can be returned in the
type field of VerifierAuthenticationError.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:
generateDeviceKeyretrieveCredentialsretrieveCredentialsUsingAuthorizationSessionAll 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.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.setNfcConfiguration and getNfcConfiguration - 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.
The SDK now supports the Token Status List Draft 14 specification while maintaining existing support for Draft 3.
application/statuslist+cwt content type header as defined in Section 8.2 of the specification,
while maintaining support for the existing mattr-statuslist+cwt type.Updated COSE algorithms (as per RFC 9864) strengthen cryptographic compatibility and ensure continued compliance with evolving standards.
iOS Platform
DiscoveredCredentialOffer on devices running iOS 17.0 or
earlier.Android Platform
Branding.name value was not set.iOS Platform
retrieveCredentialsUsingAuthorizationSession would fail on iOS devices running iOS
17.0 or earlier.This enhancement allows applications to implement the OpenID4VCI issuance workflow within embedded WebViews while maintaining full control over the redirect flow.
Applications can now:
createAuthorizationSession method to initiate the flow. This returns an AuthorizationSession object
containing both the authorizeUrl and codeVerifier properties.authorizeUrl in a WebView to handle user authentication and consent.redirectUri, then extract the
authorization code from the returned URL.retrieveCredentialsUsingAuthorizationSession method, passing in
the AuthorizationSession and extracted authorization code.const from enums: UserAuthenticationBehavior and UserAuthenticationTypeiOS Platform
UserAuthenticationType was set to .biometricOrPasscode.addCredential with a credential that could not be verified against any stored trusted
issuer certificate incorrectly threw AddMobileCredentialError.certificateNotFound instead of
AddMobileCredentialError.invalidCredential.Android Platform
retrieveCredentials to hang indefinitely.The following changes reflect the update of the SDK's spelling convention from UK English to US English.
initialise function to initialize.deinitialise function to deinitialize.MobileCredentialHolderError.AuthenticationCancelled to
MobileCredentialHolderError.AuthenticationCanceled.MobileCredentialHolderError.InvalidAuthorisationRequestUri to
MobileCredentialHolderError.InvalidAuthorizationRequestUri.MobileCredentialHolderError.InvalidAuthorisationRequestVerifiedByCertificate to
MobileCredentialHolderError.InvalidAuthorizationRequestVerifiedByCertificate.MobileCredentialHolderError.InvalidAuthorisationRequestVerifiedByDomain to
MobileCredentialHolderError.InvalidAuthorizationRequestVerifiedByDomain.getCredential method was updated as follows:MobileCredentialVerificationFailureType.TrustedIssuerCertificateNotFound
when the credential cannot be verified due to missing a matched trusted issuer certificate.Added a msoHash to the MobileCredential and MobileCredentialMetadata types. 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 the getCredential method.
iOS Platform
IssuerNamespaces field, 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 supports credential claiming using the OID4VCI Pre-Authorized Code Flow. Accordingly, the following changes have been introduced:
Method Signatures:
retrieveCredentials method now accepts:String, instead of the previous CredentialOfferResponse type for the
credentialOffer parametertransactionCodeautoTrustMobileIaca and redirectUri parameters are now set in the initialise method, whereas previously
they were parameters of retrieveCredentials.discoverCredentialOffer and are now managed
interally to the SDK:authorizeEndpoint,tokenEndpoint,credentialEndpoint,mdocIacasUridiscoverCredentialOffer:TransactionCode structThe initialise method now allows configuring how biometric authentication is performed. To allow this the following
changes were introduced:
UserAuthenticationConfiguration object:UserAuthenticationConfiguration.userAuthenticationBehavior supports the following options:UserAuthenticationBehavior.Always requires user authentication for all supported operationsUserAuthenticationBehavior.None no user authentication is requiredUserAuthenticationBehavior.OnDeviceKeyAccess requires user authentication when presenting or issuing a
credentialUserAuthenticationBehavior.OnInitialise requires user authentication when initialising the SDKUserAuthenticationConfiguration.userAuthenticationType is iOS only and supports the following options:UserAuthenticationType.BiometricOnly only biometric authentication is allowedUserAuthenticationType.BiometricOrPasscode authentication with either biometrics or device passcodeuserAuthRequiredOnInitialise boolean parameter in the initialise method with
userAuthenticationConfiguration of type UserAuthenticationConfiguration.MobileCredentialHolderErrorType.UserAuthenticationOnInitChanged error type to
MobileCredentialHolderErrorType.UserAuthenticationConfigurationChanged.CredentialIssuanceOptions to CredentialIssuanceConfigurationIn 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:
discoverCredentialOffer no longer throws the following errors:DiscoverCredentialOfferErrorType.CredentialOfferNotFoundDiscoverCredentialOfferErrorType.SupportedCredentialsNotFoundDiscoverCredentialOfferErrorType.CredentialOfferNotInCredentialIssuerMetadataDiscoverCredentialOfferErrorType.IssuerMetadataServiceErrorDiscoverCredentialOfferErrorType.FailedToDiscoverCredentialOffer**To see the full list of errors that discoverCredentialOffer may throw, refer to this method in the
SDK documentation.
**
retrieveCredentials no longer throws the following errors:RetrieveCredentialsErrorTypes.AuthCodeNotFoundRetrieveCredentialsErrorTypes.AuthenticationFailedRetrieveCredentialsErrorTypes.CertificateNotFoundRetrieveCredentialsErrorTypes.DeviceKeyGenerationErrorRetrieveCredentialsErrorTypes.GenerateAuthorisationUrlFailedRetrieveCredentialsErrorTypes.RedirectUriNotFoundRetrieveCredentialsErrorTypes.InvalidTransactionCodeRetrieveCredentialsErrorTypes.WebAuthenticationFailedRetrieveCredentialsErrorTypes.FailedToDiscoverCredentialOfferaddCredential method can now be used to add credentials with a
future validity period to the storage.First GA release as a standalone SDK.
Generated using TypeDoc