Offer a credential to a wallet holder
Introduction
The following guide will show you how to take a credential created directly using the Create credential endpoint and offer it to someone using a digital wallet to hold.
This method assumes you have a secure way to obtain the subject identifier (for example using DID Auth for a new interaction or by using a previously issued credential) and are able to authenticate the user separately from the issuance flow, for example logging into a session on a website/portal or in a physical setting.
Another example use case is re-issuing previously issued credentials, by using the information held about the user. This may start by first revoking the previous credential, then issuing a new credential before sending in a secure DID message to the wallet.
As these messages are sent directly to the wallet it does not require the user to go to a website or perform any action other than choosing to store the new credential.
Offering an issued credential to a wallet holder requires the following steps to be performed, which this guide will take you through:
Create a credential using a subject DID from the user's wallet
Construct a secure DID message & encrypt using the subject DID as the recipient
Send using either secure DID messaging or make it available through QR code/deep-link.
Prerequisites
Access to the MATTR VII APIs. If you’re experiencing any difficulties, contact us.
A postman collection (optional): We have created a curated collection of API requests dedicated to our platform, you can try it out by following this guide.
High-level steps
Overall, you will be using the following endpoints from our platform, they are:
Encrypt message (To encrypt the credential you created)
Send message (To send the credential you just encrypted to a wallet)
Step 1:
1POST https://YOUR_TENANT_URL/v2/credentials/web-semantic/configurations
Creating a DEDICATED credential that is ONLY catering to a particular holder
You can create and encrypt any Web Credential using MATTR VII, but for it to be successfully claimed by a wallet the credential needs to have an embedded association/binding to the wallet when it is created. The way you can achieve this is by utilising the DID provided by the holder’s wallet, and ensuring it is represented as the subject DID of the credential.
Pre-steps:
In order to create a credential that can be successfully sent to a holder, you need to first complete the following steps:
Obtain the wallet DID from the holder – Let's call it
RECEIVER_WALLET_DID
. It looks likedid:key:placeholder
Retrieve the DID Document associated with the Issuer DID - The response payload from the issuing party, let's call it
ISSUER_DID_DOCUMENT
You can obtain the DID Document by retrieving the response body from any of the following endpoints:
POST - {{ tenantUrl }}/v1/dids
(Endpoint for creating a DID):GET - {{ tenantUrl }}/v1/dids
(Endpoint for retrieving a list of DIDs)
The ISSUER_DID_DOCUMENT
should look like the below:
1{
2 "did": "did:web:organization.com",
3 "localMetadata": {
4 "keys": [
5 {
6 "kmsKeyId": "a0cba537-ffe1-486d-aedd-6ead80e75519",
7 "didDocumentKeyId": "did:web:organization.com#2vcj3MjR4d"
8 },
9 {
10 "kmsKeyId": "250c4e1f-bae3-44ca-9f4e-4f7ff15851e2",
11 "didDocumentKeyId": "did:web:organization.com#CU6dJt9p8t"
12 }
13 ],
14 "registered": 1674421454614,
15 "initialDidDocument": {
16 "id": "did:web:organization.com",
17 "@context": "https://w3.org/ns/did/v1",
18 "publicKey": [
19 {
20 "id": "did:web:organization.com#2vcj3MjR4d",
21 "type": "Ed25519VerificationKey2018",
22 "controller": "did:web:organization.com",
23 "publicKeyBase58": "2vcj3MjR4dSKq5asFQ9oor7iZsqTKTfBpjLHgaP15Y24"
24 }
25 ],
26 "keyAgreement": [
27 {
28 "id": "did:web:organization.com#CU6dJt9p8t",
29 "type": "X25519KeyAgreementKey2019",
30 "controller": "did:web:organization.com",
31 "publicKeyBase58": "CU6dJt9p8twE4hmyGVFbVpUMmu6G732bVgD1tNupwYY7"
32 }
33 ],
34 "authentication": [
35 "did:web:organization.com#2vcj3MjR4d"
36 ],
37 "assertionMethod": [
38 "did:web:organization.com#2vcj3MjR4d"
39 ],
40 "capabilityDelegation": [
41 "did:web:organization.com#2vcj3MjR4d"
42 ],
43 "capabilityInvocation": [
44 "did:web:organization.com#2vcj3MjR4d"
45 ]
46 }
47 }
48}
Guidelines to construct the request body:
With these steps complete, you can then follow these guidelines to construct the request body for this endpoint:
subjectId
-> UseRECEIVER_WALLET_DID
as valuename
-> General name for the credentialdescription
-> Brief description of the credentialclaims
-> Any JSON bodyissuer.id
->ISSUER_DID_DOCUMENT.did
Once you have issued your
Credential
, yourcredential
field of the request body will have a payload that looks similar to this example:
1{
2"payload": {
3 "@context": [
4 "https://schema.org"
5 ],
6 "type": ["CourseCredential"],
7 "issuer": {
8 "id": "did:web:organization.com",
9 "name": "tenant"
10 },
11 "expirationDate":"2024-02-07T06:44:28.952Z",
12 "credentialSubject": {
13 "id": "did:key:z6MkfxQU7dy8eKxyHpG267FV23agZQu9zmokd8BprepfHALi",
14 "givenName": "Chris",
15 "familyName": "Shin",
16 "educationalCredentialAwarded": "Certificate Name"
17 },
18 "proof": {
19 "type": "Ed25519Signature2018",
20 "created": "2021-07-26T01:05:06Z",
21 "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..o6hnrrWpArG8LQz2Ex_u66_BtuPdp3Hkz18nhNdNhJ7J1k_2lmCCwsNdmo-kNFirZdSIMzqO-V3wEjMDphVEAA",
22 "proofPurpose": "assertionMethod",
23 "verificationMethod": "did:key:z6MkndAHigYrXNpape7jgaC7jHiWwxzB3chuKUGXJg2b5RSj#z6MkndAHigYrXNpape7jgaC7jHiWwxzB3chuKUGXJg2b5RSj"
24 }
25 }
26}
The credential.credentialSubject.id
is critical to ensure that the credential is subject-bound to the wallet (It's the same DID as RECEIVER_WALLET_DID
). This same DID needs to be used to construct a secure DID message intended only for that recipient.
In short, credential.credentialSubject.id
has to be the same as RECEIVER_WALLET_DID
We'll elaborate on why this has to be the case later on in this tutorial.
Step 2:
1POST https://YOUR_TENANT_URL/v1/messaging/encrypt
Encrypting the credential you just created as a message
You need to construct the message payload in a particular way to be able to use the secure DID messaging capabilities.
The payload of the message consists of the parameters:
senderDidUrl
-> Must be a valid DID URL (that includes a #ref to a specific key in the Issuer's DID document) available on your tenant and a key that supportskeyAgreement
. You can find thekeyAgreement
in the DID document by inspectingISSUER_DID_DOCUMENT.localMetadata.initialDidDocument.keyAgreement[0].id
recipientDidUrls
->Array<string>
, where you addRECEIVER_WALLET_DID
into the array. The reason we do it is that it's important the holder of the credential is in control of this DID as once it is encrypted only that recipient is able to view the message.payload.id
-> Randomly generated UUID (V4)payload.type
- > Use"https://mattr.global/schemas/verifiable-credential/offer/Direct"
as value. The wallet needs this value to determine how to respond to the message.payload.from
->ISSUER_DID_DOCUMENT.did
payload.to
-RECEIVER_WALLET_DID
payload.created_time
-> Unix timestamp but as a string of integers, such as"1676570528"
, not1676570528
.payload.body.credentials
->Array<Credential>
, where you provide an array of one or multiple credentials that are all bound to theDID_RECEIVER_WALLET
you want to send them to.payload.body.domain
->{{ tenant_subdomain }}.vii.mattr.global
wheretenant_subdomain
is the same subdomain you used to createISSUER_DID_DOCUMENT
Construct the message
You need to construct the message in a certain way to be able to use the secure DID messaging capabilities.
Message template
This is what the payload
section of your request body should look like:
1{
2 "id": "{{ uuid }}",
3 "type": "https://mattr.global/schemas/verifiable-credential/offer/Direct",
4 "to": [
5 "{{ RECEIVER_WALLET_DID }}"
6 ],
7 "from": "{{ ISSUER_DID_DOCUMENT.did }}",
8 "to": [{{ RECEIVER_WALLET_DID }}],
9 "created_time": "1624509675690",
10 "body": {
11 "credentials": [{{ credential }}],
12 "domain": "{{ YOUR_TENANT_URL}}"
13 }
14}
Now, let's encrypt the message
Once the message payload has been constructed, you can use it as the payload
section within the request body for the endpoint.
Full payload template - Request body
1{
2 "senderDidUrl": "{{ ISSUER_DID_DOCUMENT.localMetadata.initialDidDocument.keyAgreement[0].id }}",
3 "recipientDidUrls": [ "{{ RECEIVER_WALLET_DID }}"],
4 "payload": {
5 "id": "{{ uuid }}",
6 "type": "https://mattr.global/schemas/verifiable-credential/offer/Direct",
7 "from": "{{ ISSUER_DID_DOCUMENT.did }}",
8 "to": [{{ RECEIVER_WALLET_DID }}],
9 "created_time": 1624509675690,
10 "body": {
11 "credentials": [{{ credential }}],
12 "domain": "YOUR_TENANT_URL"
13 }
14 }
15}
The DID used in messaging may need to be different from the DID used to issue the credential. For example, BLS key DIDs used to issue ZKP-enabled credentials cannot be used for messaging because they have no key valid for
keyAgreement
.
Full example
Endpoint: POST - {{ tenantUrl }}/core/v1/messaging/encrypt
Request body:
1{
2 "senderDidUrl": "did:web:organization.com#z6LShWb1DVC2gkxoQ91VwHmNhci2A4NdVH4srFvLiTP6ETBK",
3 "recipientDidUrls": [
4 "did:key:z6MkfxQU7dy8eKxyHpG267FV23agZQu9zmokd8BprepfHALi"
5 ],
6 "payload": {
7 "id": "c80cf529-1449-42b0-a972-ee975720859d",
8 "type": "https://mattr.global/schemas/verifiable-credential/offer/Direct",
9 "to": ["did:key:z6MkfxQU7dy8eKxyHpG267FV23agZQu9zmokd8BprepfHALi"],
10 "from": "did:key:z6MkndAHigYrXNpape7jgaC7jHiWwxzB3chuKUGXJg2b5RSj",
11 "created_time": 1624509675690,
12 "body": {
13 "credentials": [
14 {
15 "@context": [
16 "https://www.w3.org/2018/credentials/v1",
17 "https://schema.org"
18 ],
19 "type": ["VerifiableCredential", "CourseCredential"],
20 "issuer": {
21 "id": "did:web:organization.com",
22 "name": "tenant"
23 },
24 "issuanceDate": "2021-07-26T01:05:05.152Z",
25 "credentialSubject": {
26 "id": "did:key:z6MkfxQU7dy8eKxyHpG267FV23agZQu9zmokd8BprepfHALi",
27 "givenName": "Chris",
28 "familyName": "Shin",
29 "educationalCredentialAwarded": "Certificate Name"
30 },
31 "proof": {
32 "type": "Ed25519Signature2018",
33 "created": "2021-07-26T01:05:06Z",
34 "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..o6hnrrWpArG8LQz2Ex_u66_BtuPdp3Hkz18nhNdNhJ7J1k_2lmCCwsNdmo-kNFirZdSIMzqO-V3wEjMDphVEAA",
35 "proofPurpose": "assertionMethod",
36 "verificationMethod": "did:key:z6MkndAHigYrXNpape7jgaC7jHiWwxzB3chuKUGXJg2b5RSj#z6MkndAHigYrXNpape7jgaC7jHiWwxzB3chuKUGXJg2b5RSj"
37 }
38 }
39 ],
40 "domain": "YOUR_TENANT_URL"
41 }
42 }
43}
Response:
The response body contains the JWE
. Let's call this whole response payload MESSAGE_ENCRYPTED
, as we'll be using it in the next section.
1{
2 "jwe": {
3 "protected": "eyJhbGciOiJYQzIwUCJ9",
4 "recipients": [
5 {
6 "header": {
7 "alg": "ECDH-1PU+A256KW",
8 "kid": "did:key:z6MkfxQU7dy8eKxyHpG267FV23agZQu9zmokd8BprepfHALi#z6LSoYqvKWzd8faMroS4WMHRfzeDR22w5nrcGEi9MRV4BEYA",
9 "epk": {
10 "kty": "OKP",
11 "crv": "x25519",
12 "x": "ovKlBgAF969Mpa6XYhV6imLcX4ZyVQQTpU3FkjFKk2Y"
13 },
14 "skid": "did:key:z6MksHbxLQoQvsPRezXsJJiKXuaV9frAiuwKfbuHHTRn53jx#z6LSkHGWvAejiTJtKte98QAJmeSDaMtJMoupTba471nZRQhc"
15 },
16 "encrypted_key": "pZwsbPa7Vfq6KrKKLEg1jOFFkBRufsTOjrEZX6fwnu6rpQt8G_O42Q"
17 }
18 ],
19 "ciphertext": "wOiJL0zmZSaSdAk3Wn5m_XzeyiVvpJXRX3FTy0ivr3D3DTibge2I7m6DJ3kaDmXi17sy2cL0r3lsddxBcXEPDfrL8o6y5oIyodcQAo4tMY4IOXdsFHN4cTWjOyrsZhT-1GGb0QYyQ7LgCE7WgYdMX-fBetr8fhVxAoVeyYkBxRhXhF47elWlNqoLT7dfsUVYCPBjY0GN0ciQOzBvcplB8hrqVWaTvdbpgoPIGGKxcXl907gnIAX8rzFcRfh66t6M2SlGZ5pCeDvlne-StPxvIxvGJaQq02tWuA2Yykz5Gw6zz5xmPSrj7yyy26ABSM4yjQcu2q-payWQx1lkGaLrPpsbhKzq5KcXNlviz6r3aw3ERt4OO-NxmBu4ZCeK1Uvfo_wXwTawOpdjF6RB7RRjO5TJ1fGEWjpl1p84T0e-n6CE_Kxibklh4bucmx55F1rgQc1280C0k4DNJlplhoNGlFyOfaYBraT-vOJ0Fv-hKpv41npGf_uCr56Cjb4pKvMEngpAA2dglfMO0NBN5hf_FdoC6g17h4PWxcBnuCDRQcDfHvopCuCfU2H4saL07R-YRcokis2tBii7FZKS7F-eQozHzgYl68ZI3Cd5eo-4VUp3e1Xmd-b53mF3bRutV9JcY7KA1AQnwm2yyTFz0ss7a21KsYZHUi-eIhbaEf88BiMrblvp4ztDPuXUmwG4RowoRd5ZSJsdOHrkm2fniyISLGaPgcSeot22_HHsXf8bqhyxNbr6e4ghTuVZgTBBpv15DT2KSj3z3_2TgeD6VpIFwJQm1Dn_hZnSpFx-h57nsEyAAW5C9XoVJ5usnzn7TQJtZM6wsFFGd1Bgs8Xmf0p79J-QXkAWmhDi6mct5unsEnr52hnzGyLfsoH8YUjffkI55U86JZKrcMycV92IN6jF4cMoe8FbfVyu4pNrh4vKIkgVqJO0B50z0OIk8WEYIV1HoWxIzXiH6VLiC5QEZaCFyVUOnr4PFsNICLEedYwE6w0XmR2fpeMz529RPamJPYlBb9dZMGJ2RL-RnJYIH8BbhxN08EFS-4RXl27PjRoam2W6fR3fbyrObfh4H6JwXXi4ATelcBucE4zZUMrjsXMbW4CrduIis0c0f8eOPeGV4uW4W9lg4-DbsUOYY1frBSv6_1krmEvQQLgu087KfLgWMz7wqNO7UuF96ECIi7Z1yPCwx4vmtKOJN5lbFXZkzTCtV4-bltNr9PzLBJF4krqNJkwEgKe3kzrAnABKJQx1aDATk8gUJUu14635hduGBWPrY3b_isVr9tzflkCMFXq5SXV24YYCAjQsTXIRbJyV5756NwiT2L7FqzgzLmd3X6hZ5LCjv9KJwDEVCWTN9v2Zbmi8WFwrDz5LeokLGA4_Km48aJYMGpxPmL0wkEXynkIX0IhJrEu9uxEKHzEia_WjDIw80VwghZpXGVw3jYDs5R7O-zhv2lcR3UXJr_XMroe7jAV5pqWop_-ek1r7Qpt-rudjS3q_zC-uuG0SkXsL47Ni92e3MPyeDjukWAamMx7HqTx_azNL9JeeZ-w_8qd6x4wKo6qB7R0-WDFsOXHYM8HT5Aw6sKX48Dl0VfZaBE4JBXTVWTs4C9n4p3gu11bRB-tj01c3usw0vx3N-EIs5Y6cXcx3UN0O2ykWF3jCpEecUNCIzNKFTDrjALZXFvzlrdeyW5QO6sGdSVIsAZ4MDlTLRen0rzJkmw0cDmvN0OG6TvVgBoIv-Kc35g-4I8FQuUW-pIS9gQONYmCgXkQfxzjJdrcMCtQ1sV9kcg5CCirQ3KYH-5c3GhriDrNZIGJX3XkERFR9CqPFU6RSocReOr0iAx8LtssuiE1X2OeywQaAop8DJ1aQ3xaQwJQGCWSzKu_49ee6RhqSpq0EyPILxwqoHhP38NKlw5F5KGdWo6FqEzIcFVOOO160mv_yeYnIOIUnQEOGxcWSKVCiJmMcXadxtEWk2jqItbJiDxoOWs4d34eaWebVyoNOhcaim7UZQq0tE-GpFi8SZZmOmnIxL0lgZYYkvWH5WVY-n7Be6c9KoMYvQVFQ69EndcqS0zLV6unV0aZ-3CTXU1CvfSKZ1obsEozE1elYZawKiAUXQEoe2hhSmd63b3QSbduLDPs=",
20 "iv": "QKTq99Y9NjnWIDvU1XldP23j5eqXamrf",
21 "tag": "TXfEcE1wFMOOjE0GCCI7BA=="
22 }
23}
Step 3: Send the message
Once you have an encrypted message containing the credential in a format that a wallet can understand, you need to make it available to the holder.
This can be achieved in different ways;
API: Secure DID messaging to the wallet, with push notification
QR code: Host the message and reference in a QR code or deeplink
API:
Sending the encrypted credential to the wallet as a message
By using the MATTR VII platform messaging endpoint, you are able to send messages to recipients and if they have registered their MATTR mobile wallet to accept messages using an inbox, they will receive a push notification or be alerted the next time they open the app.
Specify the RECEIVER_WALLET_DID
as the to
value and use MESSAGE_ENCRYPTED.jwe
body of the encrypted message as the message
body to send using the endpoint for sending messages
1POST https://YOUR_TENANT_URL/v1/messaging/send
Request body:
1{
2 "to": "{{ RECEIVER_WALLET_DID }}",
3 "message": {{ MESSAGE_ENCRYPTED.jwe }}
4}
Response
A 200
response indicates that the message payload has been sent to the service endpoint of the dereferenced DID Document (or the default MATTR service endpoint).
QR code:
Host the secure message and redirect using QR code/Deep link
The MATTR mobile wallet will follow valid 302
redirects to online resources, this allows you to make the secure message available to wallet holders and construct a URL that can be included in a QR code or deep link.
To host the message you would need to first base64url
encode the jwe to be URL safe.
The jwe
you'll be using can be extracted from MESSAGE_ENCRYPTED.jwe
1https://YOUR_HOST_PROVIDER.com?request={{base64url(jwe)}}
Then create a redirect to this hosted message.
1Redirect Content
2redirectid=1234567. request=ewogICAgInByb3RlY3RlZCI6ICJleUpoYkdjaU9pSllRekl3VUNKOSIsCiAgICAicmVjaXBpZW50cyI6IFsKICAgICAgewogICAgICAgICJoZWFkZXIiOiB7CiAgICAgICAgICAiYWxnIjogIkVDREgtMVBVK0EyNTZLVyIsCiAgICAgICAgICAia2lkIjogImRpZDprZXk6ejZNa2Z4UVU3ZHk4ZUt4eUhwRzI2N0ZWMjNhZ1pRdTl6bW9rZDhCcHJlcGZIQUxpI3o2TFNvWXF2S1d6ZDhmYU1yb1M0V01IUmZ6ZURSMjJ3NW5yY0dFaTlNUlY0QkVZQSIsCiAgICAgICAgICAiZXBrIjogewogICAgICAgICAgICAia3R5IjogIk9LUCIsCiAgICAgICAgICAgICJjcnYiOiAieDI1NTE5IiwKICAgICAgICAgICAgIngiOiAib3ZLbEJnQUY5NjlNcGE2WFloVjZpbUxjWDRaeVZRUVRwVTNGa2pGS2syWSIKICAgICAgICAgIH0sCiAgICAgICAgICAic2tpZCI6ICJkaWQ6a2V5Ono2TWtzSGJ4TFFvUXZzUFJlelhzSkppS1h1YVY5ZnJBaXV3S2ZidUhIVFJuNTNqeCN6NkxTa0hHV3ZBZWppVEp0S3RlOThRQUptZVNEYU10Sk1vdXBUYmE0NzFuWlJRaGMiCiAgICAgICAgfSwKICAgICAgICAiZW5jcnlwdGVkX2tleSI6ICJwWndzYlBhN1ZmcTZLcktLTEVnMWpPRkZrQlJ1ZnNUT2pyRVpYNmZ3bnU2cnBRdDhHX080MlEiCiAgICAgIH0KICAgIF0sCiAgICAiY2lwaGVydGV4dCI6ICJ3T2lKTDB6bVpTYVNkQWszV241bV9YemV5aVZ2cEpYUlgzRlR5MGl2cjNEM0RUaWJnZTJJN202REoza2FEbVhpMTdzeTJjTDByM2xzZGR4QmNYRVBEZnJMOG82eTVvSXlvZGNRQW80dE1ZNElPWGRzRkhONGNUV2pPeXJzWmhULTFHR2IwUVl5UTdMZ0NFN1dnWWRNWC1mQmV0cjhmaFZ4QW9WZXlZa0J4UmhYaEY0N2VsV2xOcW9MVDdkZnNVVllDUEJqWTBHTjBjaVFPekJ2Y3BsQjhocnFWV2FUdmRicGdvUElHR0t4Y1hsOTA3Z25JQVg4cnpGY1JmaDY2dDZNMlNsR1o1cENlRHZsbmUtU3RQeHZJeHZHSmFRcTAydFd1QTJZeWt6NUd3Nnp6NXhtUFNyajd5eXkyNkFCU000eWpRY3UycS1wYXlXUXgxbGtHYUxyUHBzYmhLenE1S2NYTmx2aXo2cjNhdzNFUnQ0T08tTnhtQnU0WkNlSzFVdmZvX3dYd1Rhd09wZGpGNlJCN1JSak81VEoxZkdFV2pwbDFwODRUMGUtbjZDRV9LeGlia2xoNGJ1Y214NTVGMXJnUWMxMjgwQzBrNEROSmxwbGhvTkdsRnlPZmFZQnJhVC12T0owRnYtaEtwdjQxbnBHZl91Q3I1NkNqYjRwS3ZNRW5ncEFBMmRnbGZNTzBOQk41aGZfRmRvQzZnMTdoNFBXeGNCbnVDRFJRY0RmSHZvcEN1Q2ZVMkg0c2FMMDdSLVlSY29raXMydEJpaTdGWktTN0YtZVFvekh6Z1lsNjhaSTNDZDVlby00VlVwM2UxWG1kLWI1M21GM2JSdXRWOUpjWTdLQTFBUW53bTJ5eVRGejBzczdhMjFLc1laSFVpLWVJaGJhRWY4OEJpTXJibHZwNHp0RFB1WFVtd0c0Um93b1JkNVpTSnNkT0hya20yZm5peUlTTEdhUGdjU2VvdDIyX0hIc1hmOGJxaHl4TmJyNmU0Z2hUdVZaZ1RCQnB2MTVEVDJLU2ozejNfMlRnZUQ2VnBJRndKUW0xRG5faFpuU3BGeC1oNTduc0V5QUFXNUM5WG9WSjV1c256bjdUUUp0Wk02d3NGRkdkMUJnczhYbWYwcDc5Si1RWGtBV21oRGk2bWN0NXVuc0VucjUyaG56R3lMZnNvSDhZVWpmZmtJNTVVODZKWktyY015Y1Y5MklONmpGNGNNb2U4RmJmVnl1NHBOcmg0dktJa2dWcUpPMEI1MHowT0lrOFdFWUlWMUhvV3hJelhpSDZWTGlDNVFFWmFDRnlWVU9ucjRQRnNOSUNMRWVkWXdFNncwWG1SMmZwZU16NTI5UlBhbUpQWWxCYjlkWk1HSjJSTC1SbkpZSUg4QmJoeE4wOEVGUy00UlhsMjdQalJvYW0yVzZmUjNmYnlyT2JmaDRINkp3WFhpNEFUZWxjQnVjRTR6WlVNcmpzWE1iVzRDcmR1SWlzMGMwZjhlT1BlR1Y0dVc0VzlsZzQtRGJzVU9ZWTFmckJTdjZfMWtybUV2UVFMZ3UwODdLZkxnV016N3dxTk83VXVGOTZFQ0lpN1oxeVBDd3g0dm10S09KTjVsYkZYWmt6VEN0VjQtYmx0TnI5UHpMQkpGNGtycU5Ka3dFZ0tlM2t6ckFuQUJLSlF4MWFEQVRrOGdVSlV1MTQ2MzVoZHVHQldQclkzYl9pc1ZyOXR6ZmxrQ01GWHE1U1hWMjRZWUNBalFzVFhJUmJKeVY1NzU2TndpVDJMN0Zxemd6TG1kM1g2aFo1TENqdjlLSndERVZDV1ROOXYyWmJtaThXRndyRHo1TGVva0xHQTRfS200OGFKWU1HcHhQbUwwd2tFWHlua0lYMEloSnJFdTl1eEVLSHpFaWFfV2pESXc4MFZ3Z2hacFhHVnczallEczVSN08temh2MmxjUjNVWEpyX1hNcm9lN2pBVjVwcVdvcF8tZWsxcjdRcHQtcnVkalMzcV96Qy11dUcwU2tYc0w0N05pOTJlM01QeWVEanVrV0FhbU14N0hxVHhfYXpOTDlKZWVaLXdfOHFkNng0d0tvNnFCN1IwLVdERnNPWEhZTThIVDVBdzZzS1g0OERsMFZmWmFCRTRKQlhUVldUczRDOW40cDNndTExYlJCLXRqMDFjM3VzdzB2eDNOLUVJczVZNmNYY3gzVU4wTzJ5a1dGM2pDcEVlY1VOQ0l6TktGVERyakFMWlhGdnpscmRleVc1UU82c0dkU1ZJc0FaNE1EbFRMUmVuMHJ6SmttdzBjRG12TjBPRzZUdlZnQm9Jdi1LYzM1Zy00SThGUXVVVy1wSVM5Z1FPTlltQ2dYa1FmeHpqSmRyY01DdFExc1Y5a2NnNUNDaXJRM0tZSC01YzNHaHJpRHJOWklHSlgzWGtFUkZSOUNxUEZVNlJTb2NSZU9yMGlBeDhMdHNzdWlFMVgyT2V5d1FhQW9wOERKMWFRM3hhUXdKUUdDV1N6S3VfNDllZTZSaHFTcHEwRXlQSUx4d3FvSGhQMzhOS2x3NUY1S0dkV282RnFFekljRlZPT08xNjBtdl95ZVluSU9JVW5RRU9HeGNXU0tWQ2lKbU1jWGFkeHRFV2syanFJdGJKaUR4b09XczRkMzRlYVdlYlZ5b05PaGNhaW03VVpRcTB0RS1HcEZpOFNaWm1PbW5JeEwwbGdaWVlrdldINVdWWS1uN0JlNmM5S29NWXZRVkZRNjlFbmRjcVMwekxWNnVuVjBhWi0zQ1RYVTFDdmZTS1oxb2JzRW96RTFlbFlaYXdLaUFVWFFFb2UyaGhTbWQ2M2IzUVNiZHVMRFBzPSIsCiAgICAiaXYiOiAiUUtUcTk5WTlOam5XSUR2VTFYbGRQMjNqNWVxWGFtcmYiLAogICAgInRhZyI6ICJUWGZFY0Uxd0ZNT09qRTBHQ0NJN0JBPT0iCiAgfQ
QR code
For a QR code you would need to construct a URL to be;
1didcomm://https://YOUR_HOST_PROVIDER.com?redirectid=1234567
Using an online service the QR code would look like this https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=didcomm://https://YOUR_HOST_PROVIDER.com?redirectid=1234567
Deep link
For a deep-link you would need to perform another base64url encoding of the didcomm://
URL;
1echo -n 'didcomm://https://YOUR_HOST_PROVIDER.com?redirectid=1234567' | base64url
Then construct the URL to include the bundle id of the wallet;
1global.mattr.wallet://accept/ZGlkY29tbTovL2h0dHBzOi8vWU9VUl9IT1NUX1BST1ZJREVSLmNvbT9yZWRpcmVjdGlkPTEyMzQ1Njc
By following this URL whilst on your device, it will open the MATTR mobile wallet, follow the redirect you have configured and navigate to the Credential Offer screen in the wallet, where you can store the credential.
Try it out
Make sure you have the MATTR Wallet app installed and have accepted the notification request during the onboarding steps.
First, obtain a DID from the Mobile Wallet either a using DID Auth or by copying the 'Public DID' available in the Settings menu
Create a Credential and construct the message payload
Encrypt the payload
Send the encrypted payload or construct a QR code/deep-link redirect URL
On your mobile device, you should see a notification message appear. Tap on the message and authenticate using biometrics or PIN. The app should navigate you to the Credential offer screen where you can view the credential you have issued.
As long as the domain checks are valid and the credential isn't a duplicate then you will be able to Store the credential in your wallet.
The MATTR mobile wallet will check for duplicate credentials, these are credentials that contain the exact same proofs.
Viewing the credential is as simple as tapping on the Credential card. Each time the credential is opened a validity check is performed.