Request or download the MATTR Pi SDK Trial Licence Agreement and the MATTR Customer Agreement and review these terms.
In this SDK mDocs are referred to as Mobile credentials, CWT credentials are referred to as Compact credentials and JSON credentials are referred to as Web Credentials.
Refer to our SDK Docs landing page for step-by-step instructions to gain access to any of our SDKs.
Please reach out to us in case you need any assistance Get in touch.
Add this SDK as a dependency to the react native app:
yarn add @mattrglobal/wallet-sdk-react-native
The SDK relies on a set of peer dependencies that contain native libraries.
Install the peer dependencies:
yarn add realm@12.1.0 react-native-file-access@^3.1.1 @mattrglobal/rn-bbs-signatures@^1.1.0 react-native-get-random-values@^1.11.0 @mattrglobal/react-native-cryptography@^2.1.1 @mattrglobal/pairing-crypto-rn@^0.4.1
Make sure the following repository is included under android/build.gradle
> allprojects.repositories
:
allprojects {
repositories {
...
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
...
}
}
Add the pod for bbs-signatures
to the podfile in ios/Podfile
:
pod 'bbs-signatures', :git => 'https://github.com/mattrglobal/ffi-bbs-signatures'
Run pod install:
cd ios && pod install
Add arm64
to all profiles under: xcode -> Build Settings -> Excluded Architectures -> Any iOS Simulator SDK, it
should show the following changes under xxx.xcodeproj
for each of the profiles
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
If your app was initially created with react-native@0.61.*
or earlier versions, you may need to update your
ios/*.xcodeproj
configuration. Any reference of the DEAD_CODE_STRIPPING
flag must be removed or set to YES
, this
is required to maintain compatibility for the newer & older versions of react-native
.
- DEAD_CODE_STRIPPING = NO;
Initialise a wallet instance
import { initialise } from "@mattrglobal/wallet-sdk-react-native";
const initialiseWalletResult = await initialise();
if (initialiseWalletResult.isErr()) {
// Handle error from initialiseWalletResult.error
return;
}
const wallet = initialiseWalletResult.value;
It is possible to maintain multiple isolated wallet instances. This can be achieved by using a different instanceId
during initialisation, as long as you close the current wallet instance before initialising a new one with a different
instanceId
.
import { initialise } from "@mattrglobal/wallet-sdk-react-native";
// to use wallet1
const initialiseWallet1Result = await initialise({ instanceId: "id1" });
if (initialiseWallet1Result.isErr()) {
// Handle error from initialiseWalletResult.error
return;
}
const wallet1 = initialiseWallet1Result.value;
// to use wallet2
await wallet1.close();
const initialiseWallet2Result = await initialise({ instanceId: "id2" });
const wallet2 = initialiseWallet1Result.value;
Destroy the wallet
You must close the wallet instance that is currently initialised before calling
destroy
, otherwise an exception will be thrown.
import { destroy } from "@mattrglobal/wallet-sdk-react-native";
await destroy({ instanceId });
Discover credential offer details via offer URI
/***
* openid-credential-offer://?credential_offer=encodeURIComponent(JSON.stringify({ credential_issuer, credentials: [{credentialId}], request_parameters? }))
*/
const uri =
"openid-credential-offer://?credential_offer=%7B%22credential_issuer%22%3A%22https%3A%2F%2Fmyissuer.example.com%22%2C%22credentials%22%3A%5B%22707e920a-f342-443b-ae24-6946b7b5033e%22%5D%2C%22request_parameters%22%3A%7B%22login_hint%22%3A%22user%40example.com%22%2C%22prompt%22%3A%22login%22%7D%7D";
const discoveryResult = await wallet.openid.issuance.discover(uri);
if (discoveryResult.isErr()) {
// Handle error from discoveryResult.error
}
const { offer } = discoveryResult.value;
Or construct an offer manually
const offer: OpenidIssuanceCredentialOffer = {
issuer: "https://example.com/",
authorizeEndpoint: "https://example.com/oauth/authorize",
tokenEndpoint: "https://example.com/oauth/token",
credentialEndpoint: "https://example.com/oauth/credential",
credentials: [
{
profile: "web-semantic",
scope: "ldp_vc:UniversityDegreeCredential",
credentialDefinition: {
"@context": ["https://www.w3.org/2018/credentials/v1"],
type: ["VerifiableCredential", "UniversityDegreeCredential"],
},
},
],
};
Configure OAuth client id and redirect uri
const clientId = "myAppClientId";
const redirectUri = "myapp://credentials/callback";
Generate an authorization url and open in a web browser
import { Linking } from "react-native";
const generateAuthorizeUrlResult = await wallet.openid.issuance.generateAuthorizeUrl({ offer, clientId, redirectUri });
if (generateAuthorizeUrlResult.isErr()) {
// Handle error from generateAuthorizeUrlResult.error
return;
}
const { url, codeVerifier } = generateAuthorizeUrlResult.value;
await Linking.openURL(url);
Handle authorization success callback
myapp://credentials/callback?code=...&iss=...
Retrieve token
const retrieveTokenResult = await wallet.openid.issuance.retrieveToken({
offer,
clientId,
redirectUri,
codeVerifier,
code: route.params.code, // code comes authorization success callback above
});
if (retrieveTokenResult.isErr()) {
// Handle error from retrieveTokenResult.error
return;
}
const { accessToken } = retrieveTokenResult.value;
Retrieve credentials
const retrieveCredentialsResult = await wallet.openid.issuance.retrieveCredentials({
offer,
accessToken,
clientId,
});
retrieveCredentialsResult.forEach((credentialOfferResult) => {
if ("error" in credentialOfferResult) {
const { offer, error } = credentialOfferResult;
// Handle error from retrieveCredentialsResult.error
} else {
const { offer, result } = credentialOfferResult;
}
});
Discover OIDC credential offer
const discoverResult = await wallet.oidc.discover("openid://discovery?issuer=https://issuer.example.com");
if (discoverResult.isErr()) {
// Handle error from discoverResult.error
return;
}
const { offer } = discoverResult.value;
Create a local subject DID for the credential
const createDidResult = await wallet.did.createDid();
if (createDidResult.isErr()) {
// Handle error from createDidResult.error
return;
}
const { did } = createDidResult.value;
Generate an OpenID authorization url to request the credential
import { Linking } from "react-native";
const genUrlResult = await wallet.oidc.generateAuthorizeUrl({ offer, did });
if (genUrlResult.isErr()) {
// Handle error from genUrlResult.error
return;
}
const { url, codeVerifier, nonce } = genUrlResult.value;
await Linking.openURL(url);
Retrieve the credential on an authorization success callback
const retrieveResult = (retrieveCredential = await wallet.oidc.retrieveCredential({
offer,
codeVerifier,
nonce,
code: route.params.code, // code comes from part of the callback url
}));
if (retrieveResult.isErr()) {
// Handle error from retrieveResult.error
return;
}
const { credential } = retrieveResult.value;
Resolve a didcomm message from a didcomm URI
const resolveDidCommUriResult = await wallet.did.messaging.resolveDidCommUri(uri);
if (resolveDidCommUriResult.isErr()) {
// Handle error from resolveDidCommUriResult.error
return;
}
const message = resolveDidCommUriResult.value;
Open a didcomm message that is signed or encrypted
import { isPresentationRequestJwm } from "wallet-sdk-react-native";
const openResult = await wallet.did.messaging.openDidCommMessage(message);
if (openResult.isErr()) {
// Handle error from openResult.error
return;
}
Verify a JSON credential
const verifyResult = await wallet.credential.webSemantic.verifyCredential({ credential });
if (verifyResult.isErr()) {
// Handle error from verifyResult.error
return;
}
const { credentialVerified, status } = verifyResult.value;
Parse a presentation request (DIDComm message)
import { isPresentationRequestJwm } from "wallet-sdk-react-native";
const openResult = await wallet.did.messaging.openDidCommMessage(message);
if (openResult.isErr() || !isPresentationRequestJwm(openResult.value)) {
return;
}
const presentationRequest = openResult.value;
Retrieve credentials matching a specific presentation request
const credentialData = [
{ id: "a", credential: credentialA },
{ id: "b", credential: credentialB },
];
const filterResult = await wallet.credential.webSemantic.filterCredentialsByQuery({
credentials: credentialData,
// Note that only the presentation request body should contain single query only, under the same query could contain multiple sub queries.
query: presentationRequest.body.query[0],
});
Create and send a presentation response for a presentation request
const createPresentationResult = await wallet.credential.webSemantic.createPresentation({
challenge: presentationRequest.body.challenge,
domain: presentationRequest.body.domain,
credentials,
holder: did,
});
if (createPresentationResult.isErr()) {
// Handle error from createPresentationResult.error
return;
}
const presentation = createPresentationResult.value;
const sendPresentationResult = await wallet.credential.webSemantic.sendPresentationResponse({
presentationRequest,
presentation,
});
Verify a CWT credential
const credentialPayload = "CSC:/1/....";
const verifyResult = await wallet.credential.compact.verifyCredential({ payload: credentialPayload });
if (verifyResult.isErr()) {
// Handle error from verifyResult.error
return;
}
if (result.value.verified) {
const { payload } = result.value;
} else {
const { reason } = result.value;
}
Verify a Semantic CWT Credential
const credentialPayload = "CSS:/1/....";
const verifyResult = await wallet.credential.compactSemantic.verifyCredential({ payload: credentialPayload });
if (verifyResult.isErr()) {
// Handle error from verifyResult.error
return;
}
if (result.value.verified) {
const { payload } = result.value;
} else {
const { reason } = result.value;
}
The @mattrglobal/wallet-sdk-react-native
package does not come with the following extensions by default.
In this SDK mDocs are referred to as Mobile Credentials.
To enable mDocs features, an additional peer dependency
@mattrglobal/mobile-credential-holder-react-native
is needed. Install the following dependency in your app.
yarn add @mattrglobal/mobile-credential-holder-react-native
mDocs presentation utilise Bluetooth connection. Make sure the NSBluetoothAlwaysUsageDescription
and
NSBluetoothPeripheralUsageDescription
descriptions are configured inside Info.plist
.
Additional configuration steps are required to bundle the native libraries.
The precompiled MATTR mDocs holder Android SDK is provided in the published NPM package.
Open the android/build.gradle
script and append the following changes:
allprojects {
repositories {
…
google()
+ maven {
+ url = "$rootDir/../node_modules/@mattrglobal/mobile-credential-holder-react-native/android/frameworks"
+ }
}
}
Include the mDocs holder extension during initialisation
import { initialise } from "@mattrglobal/wallet-sdk-react-native";
import MobileCredentialHolder from "@mattrglobal/mobile-credential-holder-react-native";
await initialise({ extensions: [MobileCredentialHolder], instanceId });
The same extension is required when destroying a wallet instance
import { destroy } from "@mattrglobal/wallet-sdk-react-native";
import MobileCredentialHolder from "@mattrglobal/mobile-credential-holder-react-native";
await destroy({ extensions: [MobileCredentialHolder], instanceId });
The mDocs holder extension utilise Apple iOS Keychain and Android Key Store to manage cryptographic keys and perform crypto operations securely. By default the policy requires user authentication before providing access to the key store (i.e. biometric or passcode).
When the mDocs holder extension is enabled, the following functions may require user authentication. This would result in an error when no suitable user authentication mechanism is setup on the device, or when authentication fails:
initialise
: when initialising a wallet instance, user authentication is required to unlock the secure storages. This can be disabled by passing the userAuthRequiredOnInitialise: false
option
wallet.openid.issuance.retrieveCredentials
: when retrieving an mDoc, user authentication is required to generate proof of possession of the credential's binding device key.
wallet.credential.mobile.sendPromixityPresentationResponse
and OnlinePresentationSession#sendResponse
: when creating either in-person or online presentation responses, user authentication is required to sign the response payload.
A grace period was put in place to prevent frequent re-authentication requests when accessing/using multiple cryptographic keys in quick succession (for example when creating an mDoc presentation involving multiple credentials and hence multiple keys).
With the mobile credential holder extension, the SDK will be able to retrieve mDocs over OpenID4VCI.
mDocs will be verified automatically as part of
retrieveCredentials
, if the mDocs issued from the remote credential issuer are not verified,retrieveCredentials
will return error instead.
import { CredentialProfileSupported } from "@mattrglobal/wallet-sdk-react-native";
const retrieveCredentialsResult = await wallet.openid.issuance.retrieveCredentials({
offer, // offer that contains mDocs
accessToken,
clientId,
});
retrieveCredentialsResult.forEach((credentialOfferResult) => {
if ("error" in credentialOfferResult) {
const { offer, error } = credentialOfferResult;
// Handle error from retrieveCredentialsResult.error
} else {
const { offer, result } = credentialOfferResult;
if (result.profile === CredentialProfileSupported.Mobile) {
const credentialId = result.credentialId;
}
}
});
The SDK manages the storage of any retrieved mDocs and these are accessible via the following functions
getCredentials
only retrieves credential metadata, without accessing the full credentials. The credential metadata doesn't include any PII information (i.e. claims' value) or verification result. If you want to get the claim values or the latest verification result of the credential, you should retrieve it from callinggetCredential
individually.
// Get an mDoc with full details
const getCredentialResult = await wallet.credential.mobile.getCredential(credentialId);
// Get all mDocs (metadata only)
const getCredentialsResult = await wallet.credential.mobile.getCredentials();
// Delete an mDoc
await wallet.credential.mobile.deleteCredential(credentialId);
The SDK only accepts mDocs that can be verified successfully by the trusted issuer certificates. The trusted issuer certificates list can be managed directly with the following functions:
// Add new trusted issuer certificates
const addCertificateResult = await wallet.credential.mobile.addTrustedIssuerCertificates(certificates);
// Get all trusted issuer certificates
const certificates = await wallet.credential.mobile.getTrustedIssuerCertificates();
// Remove one of the trusted issuer certificate
await wallet.credential.mobile.deleteTrustedIssuerCertificate(id);
You may also instruct the SDK to automatically download and add certificates into the trusted list while retrieving an mDoc via OpenID4VCI, when they are discoverable via the openid credential issuer metadata:
const retrieveCredentialsResult = await wallet.openid.issuance.retrieveCredentials({
offer, // offer that contains mDocs
accessToken,
clientId,
autoTrustMobileCredentialIaca: true, // enable auto trust
});
The mDoc holder extension supports proximity presentation, which allows the holder application to present credentials to a verifier device via Bluetooth as defined in ISO 18013-5. The following example shows how you could start and respond to a proximity credential presentation request from a verifier device.
Only one proximity presentation session is allowed at a time. You must terminate the existing session before starting a new one.
When a proximity presentation request is received, you must respond to it before any new request can be received in the same session.
The SDK follows the guidance from ISO/IEC 18013-5:2021 with a session inactivity timeout of 300 seconds. Once a proximity presentation session is created, if there is a period of inactivity that exceeds 300 seconds, the current session will be terminated with onSessionTerminated() callback.
Similar to
getCredentials
, thematchedCredentials
only contains credential metadata. If you want to get the claim values or the latest verification result of the credential, you should retrieve it by callinggetCredential
individually
// start a new presentation session
const createPresentationSessionResult = await wallet.credential.mobile.createProximityPresentationSession({
onRequestReceived: (data) => {
// request received with error
if ("error" in data) {
const { error } = data;
return;
}
const requests = data.request;
requests.map(({ request, matchedCredentials }) => {
// obtain each request with matching credentials in the mDocs storage
});
},
onConnected: (data: unknown) => {
// presentation session is connected
},
onSessionTerminated: (data: unknown) => {
// presentation session is terminated
},
});
if (createPresentationSessionResult.isErr()) {
// handle error creating presentation session
}
const { deviceEngagement } = createPresentationSessionResult.value;
// Render device engagement string on a QRCode. A verifier app should scan and use it to establish the presentation session with this holder.
// construct and send a presentation response with the selected credentials
await wallet.credential.mobile.sendProximityPresentationResponse({ credentialIds });
// terminate the session
await wallet.credential.mobile.terminateProximityPresentationSession();
The mDocs holder extension also supports online presentation, which allows the holder application to present credentials to an online verifier web application via OpenID4VP as defined in ISO 18013-7. The following example shows how you could start and respond to an online presentation request from a verifier web application.
Similar to
getCredentials
, thematchedCredentials
only contains credential metadata. If you want to get the claim values or the latest verification result of the credential, you should retrieve it by callinggetCredential
individually.
// start a new presentation session
const createPresentationSessionResult = await wallet.credential.mobile.createOnlinePresentationSession({
authorisationRequestUri: "..."
});
if (createPresentationSessionResult.isErr()) {
// handle error creating presentation session
}
const session = createPresentationSessionResult.value;
// Render the verifier information stored in `session.verifiedBy`.
// Render the list of matched credentials for each received request stored in `session.matchedCredentials` for user to select.
const { matchedCredentials } = session;
// construct and send a presentation response with the selected credentials
const sendResponseResult = await session.sendResponse({ credentialIds });
// in case of error, could either terminite the session or try to createOnlinePresentationSession again
if (sendResponseResult.isErr()) {
await session.terminateSession();
}
An online presentation request is always signed by the verifier client. By default the SDK will validate the request based on the verifier client domain. You may also instruct the SDK to strictly validate the request against a list of local trusted verifier certificates. This requires the user to set up the list of trusted verfier certificates before creating an online presentation. The list of trusted verifier certificates can be managed directly with the following functions:
// Add new trusted verifier certificates
const addCertificateResult = await wallet.credential.mobile.addTrustedVerifierCertificates(certificates);
// Get all trusted verifier certificates
const certificates = await wallet.credential.mobile.getTrustedVerifierCertificates();
// Remove one of the trusted verifier certificate
await wallet.credential.mobile.deleteTrustedVerifierCertificate(id);
// start a new presentation session with requireTrustedVerifier on
const createPresentationSessionResult = await wallet.credential.mobile.createOnlinePresentationSession({
authorisationRequestUri: "...",
requireTrustedVerifier: true
});
The Ecosystem SDK provides the capabilities of the ecosystem feature. To enable the feature, an additional peer
dependency @mattrglobal/ecosystem-sdk-react-native
is needed, which can be installed with:
yarn add @mattrglobal/ecosystem-sdk-react-native
And then include the ecosystem SDK during initialisation:
import { initialise } from "@mattrglobal/wallet-sdk-react-native";
import Ecosystem from "@mattrglobal/ecosystem-sdk-react-native";
await initialise({ extensions: [Ecosystem], ecosystem: { url } });
The same extension is also required to destroy a wallet instance:
import { destroy } from "@mattrglobal/wallet-sdk-react-native";
import Ecosystem from "@mattrglobal/ecosystem-sdk-react-native";
await destroy({ extensions: [Ecosystem] });
On initialisation, previously mentioned, the internal storage is synced with latest policy relevant to the ecosystem ID provided. In case, storage becomes out of sync, the SDK provides managing the storage manually:
// storage can be synced manually
const syncResult = await wallet.ecosystem.sync({ reset: true });
// storage can be deleted manually
const deleteResult = await wallet.ecosystem.delete();
The main features of the SDK is to provide validation of a given credential and participant, who can be an issuer or a verifier, or both, and whether the participant is authorised. This can be invoked with:
// validates the three aspects of the specified issuer
const validateIssuerResult = await Ecosystem.validateIssuer({ profile, identifier, type });
// validates the three aspects of the specified verifier
const validateVerifierResult = await Ecosystem.validateVerifier({ profile, identifier, type });
Functions that are expected to have an error path return a
Neverthrow Result type that represents either success
(Ok
) or failure (Err
).
Although this pattern is more verbose, it encourages the handling of possibly errors and reserves throwing exceptions for truly exceptional situations.
import { initialise } from "@mattrglobal/wallet-sdk-react-native";
const initialiseWalletResult = await initialise();
if (initialiseWalletResult.isErr()) {
// Handle error from initialiseWalletResult.error
return;
}
const wallet = initialiseWalletResult.value;
A utility function is provided for convenience if you decide not to handle your errors as results. This function will
simply throw an error if the function passed in returns a Result
where Result.isErr()
is true
.
import { unwrap } from "@mattrglobal/wallet-sdk-react-native";
try {
const wallet = unwrap(await initialise());
} catch (error) {
// Handle thrown error
}
react-native-fs
peer-dependency has been replaced with
react-native-file-access@^3.1.1. You must add this new
dependency in your project.@mattrglobal/react-native-cryptography@2.1.1
.mDocs
Realm database has been replaced with a custom storage system. Upgrading to this version will result in all mDocs related data being lost. This includes all trusted issuer certificates and credentials.
The credentail.mobile.getCredentials
method now returns an array of MobileCredentialMetadata
which only contains
credentials metadata, excluding Personally Identifiable Information (PII) and latest verification result.
The onRequestReceived
callback of a Proximity Presentation session now contains matchedCredentials
as an array of
MobileCredentialMetadata
which contains credentials metadata, excluding Personally Identifiable Information (PII)
and latest verification result.
The initialise
method error types were updated as follows:
UserAuthenticationOnInitChangedError
when a different userAuthRequiredOnInitialise
option has been
specified during re-initialisation of the SDK. This error type is only applicable when the
userAuthRequiredOnInitialise
option is used.UserAuthenticationBiometryLockoutError
when biometry authentication has been locked out on user's device.The credential.mobile.createProximityPresentationSession
method error types were updated as follows:
MobileCredentialHolderErrorType.UnsupportedAuthenticationOption
(Android only).The wallet.credential.mobile.sendPromixityPresentationResponse
method error types were updated as follows:
ProximityPresentationSessionErrorType.UserAuthenticationBiometryLockout
.ProximityPresentationSessionErrorType.UserAuthenticationUnrecoverableKey
.The credentail.mobile.addCredential
method error types were updated as follows:
MobileCredentialHolderErrorType.UserAuthenticationOnDeviceNotSetup
.MobileCredentialHolderErrorType.AuthenticationCancelled
.MobileCredentialHolderErrorType.UserAuthentication
.The credentail.mobile.addTrustedIssuerCertificates
method error types were updated as follows:
MobileCredentialHolderErrorType.FailedToStoreCertificate
when the given certificate is invalid.MobileCredentialHolderErrorType.InvalidCertificate
.The following error types were renamed to properly reflect that a user authetication prompt (biometric or passcode) has been cancelled by either the user or the device OS:
For the initialise
method:
UserAuthenticationCancelledError
was renamed to AuthenticationCancelledError
.For the wallet.openid.issuance.retrieveCredentials
method:
MobileCredentialHolderErrorType.UserAuthenticationCancelled
was renamed to
MobileCredentialHolderErrorType.AuthenticationCancelled
.For the wallet.credential.mobile.sendPromixityPresentationResponse
method:
ProximityPresentationSessionErrorType.UserAuthenticationCancelled
was renamed to
ProximityPresentationSessionErrorType.AuthenticationCancelled
.For the OnlinePresentationSession#sendResponse
method:
ProximityPresentationSessionErrorType.UserAuthenticationCancelled
was renamed to
ProximityPresentationSessionErrorType.AuthenticationCancelled
.mDocs
Introduced support for mDocs online presentation via OpenID4VP as defined in ISO/IEC 18013-7:2024.
The initialise
method now supports an optional parameter to control whether user authentication (biometric or
passcode) is required when initialising the SDK. By default, when this option is not provided user authentication will
be required. The SDK cannot accept further changes to this option with a particular wallet instance.
The credential.mobile.getCredential
method could return an mDoc with additional verification failure reason types:
MobileCredentialVerificationFailureType.DeviceKeyInvalid
.MobileCredentialVerificationFailureType.UnsupportedCurve
.mDocs
credential.mobile.createProximityPresentationSession
method was not returning
MobileCredentialHolderErrorType.BluetoothPermissionDenied
error when the user denies the Bluetooth permission
request.react-native-securerandom
peer-dependency is no longer required.@mattrglobal/react-native-cryptography@2.0.0
.Web Semantic Credential
await initWalletConfig({
...
credential: {
webSemantic: {
remoteContextUrlAllowList: [...], // a list of allowed remote context urls, default: []
remoteContextUrlAllowAny: false // allow any remote context, default: false
inlineContextAllowAny: false, // allow any inline context, default: false
contextValidatorMaxDepth: 10, // max level of nested JsonLD document supported during context validation, default: 10
},
},
})
To use any remote contexts, you will need to manually add them to the remoteContextUrlAllowList
array.
Web Semantic Credential
credential.webSemantic.filterCredentialsByQuery
method now filters out credentials with invalid contexts instead
of returning an error.FilterWebSemanticCredentialsByQueryError
to PresentationRequestError
.react-native-secure-key-store
library was replaced with a local secure store implementation, so peer dependency
react-native-secure-key-store
is no longer required.Mobile Credential
Web Semantic Credential
await initWalletConfig({
...
credential: {
webSemantic: {
remoteContextUrlAllowList: [...], // a list of allowed remote context urls, default: undefined, set this to [] to block any remote context
remoteContextUrlAllowAny: true, // allow any remote context, default: true
inlineContextAllowAny: true, // allow any inline context, default: true
contextValidatorMaxDepth: 10, // max level of nested JsonLD document supported during context validation, default: 10
},
},
})
Fixed network error detection for the following methods:
wallet.credential.webSemantic.createPresentation
Mobile Credential
Mobile Credential
credential.mobile.sendProximityPresentationResponse
added an optional parameter terminateSession: boolean
which
controls whether to terminate the session as a part of sending the responseMobile Credential
compact.verifyCredential
and compactSemantic.verifyCredential
assertExpiry
to assertValidUntil
assertNotBefore
to assertValidFrom
VerifyFailureReasonType
Expired
to ValidUntil
NotActive
to ValidFrom
Add support for web-semantic credentials with an issuanceDate
in the future:
issuanceDate
in the future by adding an inactive
status to
VerifyWebSemanticCredentialResult
to indicate that credential is inactiveissuanceDate
Expose NetworkError
in case a remote request fails due to a network error or timeout in the following methods:
wallet.openid.isssuance.discover
wallet.openid.isssuance.retrieveToken
Refined did.messaging.resolveDidCommUri
error results for remote DIDComm URI resolution responses, it could return
ResolveDidCommUriErrorType.NetworkError
when the DIDComm URI is unresolvableResolveDidCommUriErrorType.InvalidDidCommUri
when the resolution result does not conform to a valid DIDComm
messageImproved network error detection for the following methods:
wallet.credential.webSemantic.createPresentation
wallet.did.messaging.openDidCommMessage
@mattrglobal/bbs-signatures
dependencyThe initialise
method could return the following errors:
UserAuthenticationUnrecoverableKeyError
when user authentication key is unrecoverable, it requires
re-initialisation of the SDK. This error type is only applicable on Android platform when
@mattrglobal/mobile-credential-holder-react-native
is enabled.EcosystemInitialiseError
when failed to initialise the @mattrglobal/ecosystem-sdk-react-native
extension.Refined error type for the did.messaging.resolveDidCommUri
method to the following values:
ResolveDidCommUriErrorType.InvalidDidCommUri
when provided URI does not resolve into a did comm messageResolveDidCommUriErrorType.NetworkError
when unable to resolve the DIDComm URI due to network issueExpose NetworkError
in case a remote request fails due to a network error or timeout in the following methods:
did.messaging.openDidCommMessage
could return NetworkError
when unable to resolve a remote DID documentcredential.webSemantic.createPresentation
could return NetworkError
when unable to resolve a remote DID documentAdd Android support for mobile credential. Integration of the @mattrglobal/mobile-credential-holder-react-native
extension into wallet sdk is now supported on both iOS and Android platforms. The current functionality includes
Cache the remote DID document resolution to prevent unnecessary requests.
Add support for ecosystem functionality from @mattrglobal/ecosystem-sdk-react-native
extension. The current
functionality includes:
@mattrglobal/ecosystem-sdk-react-native
did.messaging.openDidCommMessage
to return error result for remote resolution with non 2xx responsesNo longer allow having multiple wallet instance with difference walletIds initialised at the same time. Before initialising a wallet instance with a different walletId, the current instance must be closed first.
import { initialise } from "@mattrglobal/wallet-sdk-react-native";
// Previously, the following is allowed.
const initialiseResult1 = await initialise(walletId1);
if (initialiseResult1.isErr()) {
return;
}
const wallet1 = initialiseResult1.value;
const initialiseResult2 = await initialise(walletId2);
if (initialiseResult2.isErr()) {
return;
}
const wallet2 = initialiseResult2.value;
// Now, the existing wallet must be closed first
const initialiseResult1 = await initialise(walletId1);
if (initialiseResult1.isErr()) {
return;
}
const wallet1 = initialiseResult1.value;
await wallet1.close();
const initialiseResult2 = await initialise(walletId2);
if (initialiseResult2.isErr()) {
return;
}
const wallet2 = initialiseResult2.value;
Wallet instance must be closed if it is currently initialised before calling destroy
, otherwise an exception will be
thrown.
Remove error type MalformedEncryptionKeyError that is actually unreacble on destroy
method
Realm now requires >=12.1.0
as peer dependencies to avoid security vulnerability issue in Realm 11.
refine error types for wallet.credential.webSemantic.sendPresentationResponse
SendWebSemanticPresentationResponseErrorType.FailedToSendPresentationResponse
error typeSendWebSemanticPresentationResponseErrorType.VerificationFailed
error when presentation response endpoint
returns 400 Bad Request, which indicates an failure of verifying the presentation responseSendWebSemanticPresentationResponseErrorType.VerifierUnavailable
error when presentation response endpoint,
returns 504 Gateway Timeout, which indicates the verifier is unavailable. The details of the error will contain the
verified
for the result of the presentation verification.Add support for mobile credential (iOS Only). This allows user to integrate the mobile credential functionality from
@mattrglobal/mobile-credential-holder-react-native
into the wallet sdk. The current functionality includes
wallet.did.messaging.openDidCommMessage
now checks JWM message expiries_time when available and return error if the
message is expired.
wallet.credential.webSemantic.sendPresentationResponse
now includes expires_time in the message
Support partial failure in wallet.webSemantic.retrieveCredentials
method:
retrieveCredentials
method no longer return error result if it fails to retrieve one of the credentials, instead
it returns a union of credentials and errors.
const retrieveCredentialsResult = await wallet.openid.issuance.retrieveCredentials({
offer,
accessToken,
clientId,
});
/**
* Example `retrieveCredentialsResult`
* [
* {
* offer,
* credential, // Successfully retrieved verifiable credential
* },
* {
* offer,
* error: { type, message, cause }, // Failure
* }
* ]
*/
Expose NetworkError
in case a remote request fails due to a network error or timeout in the following methods:
wallet.credential.webSemantic.verifyCredential
could return type
VerifyWebSemanticCredentialErrorType.NetworkError
wallet.credential.webSemantic.deriveCredential
could return type
DeriveWebSemanticCredentialErrorType.NetworkError
wallet.credential.webSemantic.expandCredential
could return type
ExpandWebSemanticCredentialErrorType.NetworkError
wallet.credential.webSemantic.sendPresentationResponse
could return type
SendWebSemanticPresentationResponseErrorType.NetworkError
wallet.credential.webSemantic.filterCredentialsByQuery
could return type
PresentationRequestErrorType.NetworkError
wallet.openid.issuance.retrieveCredentials
could return type RetrieveCredentialsErrorType.NetworkError
in the
new partial error format (see item above)Consolidate create
and open
into initialise
method
// Previously
import { create, open } from "@mattrglobal/wallet-sdk-react-native";
const createWalletResult = await create();
if (createWalletResult.isErr()) {
return; // Handle error from createWalletResult.error
}
const openWalletResult = await open();
if (openWalletResult.isErr()) {
return; // Handle error from openWalletResult.error
}
const wallet = openWalletResult.value;
...
// Now
import { initialise } from "@mattrglobal/wallet-sdk-react-native";
const initialiseResult = await initialise();
if (initialiseResult.isErr()) {
return; // Handle error from initialiseResult.error
}
const wallet = initialiseResult.value;
...
webSemantic.verifyCredentials
resultsisRevoked
to be true
if revocation status check failedexpired
to be false
if credential signature verification failedAdd support for React Native 0.71
realm>=11.10.2
BbsSignature2022
verifiable credentials@mattrglobal/pairing-crypto-rn
@mattrglobal/react-native-cryptography
Wallet SDK Interface:
wallet.did.create
to wallet.did.createDid
wallet.did.delete
to wallet.did.deleteDid
wallet.did.list
to wallet.did.listDids
wallet.did.resolve
to wallet.did.resolveDid
wallet.wellKnownDidConfiguration
to wallet.did.wellKnownDidConfiguration
wallet.messaging
to wallet.did.messaging
wallet.credential.isSelectivelyDisclosable
to
wallet.credential.webSemantic.isCredentialSelectivelyDisclosable
wallet.credential.derive
to wallet.credential.webSemantic.deriveCredential
wallet.credential.verify
to wallet.credential.webSemantic.verifyCredential
wallet.credential.expand
to wallet.credential.webSemantic.expandCredential
wallet.presentation.create
to wallet.credential.webSemantic.createPresentation
wallet.presentation.filterCredentialsByQuery
to wallet.credential.webSemantic.filterCredentialsByQuery
wallet.presentation.sendPresentationResponse
to wallet.credential.webSemantic.sendPresentationResponse
Manual Credential Offer:
format
with profile
const offer: OpenidIssuanceCredentialOffer = {
...,
credentials: [
{
scope: "ldp_vc:UniversityDegreeCredential",
profile: "web-semantic",
credentialDefinition: {
"@context": ["https://www.w3.org/2018/credentials/v1"],
type: ["VerifiableCredential", "UniversityDegreeCredential"],
},
}
],
};
wallet.openid.issuance.retrieveCredentials
format
with profile
{
credentials: {
credential,
profile,
did,
}[];
}
qrcode
big-integer
with bignumber.js
for the BigInt
polyfillhttpRequestTimeoutMs
) under InitOptions
and set the default value to 5
seconds./**
* openid-credential-offer://?credential_offer=encodeURIComponent(JSON.stringify({ credential_issuer, credentials: [{credentialId}], request_parameters? }))
*/
const uri =
"openid-credential-offer://?credential_offer=%7B%22credential_issuer%22%3A%22https%3A%2F%2Fmyissuer.example.com%22%2C%22credentials%22%3A%5B%22707e920a-f342-443b-ae24-6946b7b5033e%22%5D%2C%22request_parameters%22%3A%7B%22login_hint%22%3A%22ken.huang%40mattr.global%22%2C%22prompt%22%3A%22login%22%7D%7D";
const offer = unwrap(await wallet.openid.issuance.discover(uri));
Export types:
Update OpenId issuance offer types (WebSemantic)
const offer: OpenidIssuanceCredentialOffer = {
issuer: "https://example.com/",
authorizeEndpoint: "https://example.com/oauth/authorize",
tokenEndpoint: "https://example.com/oauth/token",
credentialEndpoint: "https://example.com/oauth/credential",
credentials: [
{
format: "ldp_vc",
scope: "UniversityDegreeCredential",
credentialDefinition: {
"@context": ["https://www.w3.org/2018/credentials/v1"],
type: ["VerifiableCredential", "UniversityDegreeCredential"],
},
},
],
};
retrieveCredentials
to support deprecated optionsreact-native-secure-key-store
2.0.10@mattrglobal/rn-bbs-signatures
versionGenerated using TypeDoc