Issue Credentials to Affinidi Vault Users

Issue Verifiable Credentials from your application and enable users to store it on their Affinidi Vault.

To integrate with the Credential Issuance service, you must create the Schema for your Verifiable Credentials using Schema Builder, set up a Credential Issuance Configuration, and use the Affinidi TDK’s Credential Issuance client to enable your application to issue credentials to your users.

Set up Credential Issuance Configuration

To issue a Verifiable Credential, it is required to setup the Issuance Configuration on your project, where you select the issuing wallet and supported schema to create a credential offer that the application issue.

You can easily do this using the Affinidi Portal:

  1. Go to  Affinidi Portal and click on the Credential Issuance page.

  2. Click on Create Configuration and set the following fields:

Issuing Wallet: Create a new wallet and provide the new wallet name or select an existing Wallet that will sign and issue the credentials to the user. Read more about Wallets here.

Lifetime of Credential Offer: Credential Offers have a limited lifetime to enhance security. Consumers must claim the offer within this timeframe.

Supported Schemas: List of allowed schemas for creating a credential offer. Issuance will validate the credential data based on the supported schema before creating the Credential Offer. Create the Schema through the Schema Builder.

The Credential Type ID specified on each supported schema is required as a credentialTypeId parameter when creating a Credential Offer. The JSON Schema URL and JSON-LD Context URL can be found in the Schema you have created in the Schema Builder.

  1. After setting the fields and providing the list of the supported schema, click Create.
Create Credential Issuance

Test Your Issuance Configuration

Affinidi Portal allows you to test your Credential Issuance configuration and issue Verifiable Credentials to your Affinidi Vault based on the list of supported schemas configured to ensure your setup works.

To do this, click the Test button at the top-right of the Issuance Configuration detail view.

Credential Issuance Configuration Test

Upon loading the page, the Holder’s DID is populated with your Decentralised Identifier (DID), which is used to log in to the Affinidi Portal.

You can specify the Claim Mode whether to generate a Transaction Code to claim the Verifiable Credential or claim normally without a Transaction Code.

After specifying the Claim Mode, you must select which Schema to use from the list of supported schemas in your configuration.

Credential Issuance Configuration Test Page

Selecting the Credential Type ID will dynamically render the fields based on the Schema definition. Fill out the fields and then click on the Issue Credential button to create a Credential Offer.

Once the Credential Offer is created, a popup is shown with the details like the Expiration of the Credential Offer based on your configuration, the Claim Link, and the QR code to complete the process of claiming the credential to your Affinidi Vault.

Credential Issuance Configuration Test Output

Test each Credential Type to make sure your configuration and Schema definition meet your requirements.

Create a Credential Offer

After setting up the Issuance Configuration, use the Issuance Client of the Affinidi TDK to enable your application to create a Credential Offer to Affinidi Vault users.

In this example, we will create a Credential Offer for a course completion use case. Follow the sample code below to initiate a Credential Offer to the user.

  1. Install the required libraries (in our example, we will use Credential Issuance Service).
npm install -S @affinidi-tdk/auth-provider @affinidi-tdk/credential-issuance-client
pip install affinidi_tdk_auth_provider affinidi_tdk_credential_issuance_client
  1. Import the libraries into the code. We are importing the Credential Issuance client (Credential Issuance Service) to create a Credential Offer and the Auth Provider to generate the Project Scoped Token for the Authorisation header.
import { IssuanceApi, Configuration, StartIssuanceInput } from '@affinidi-tdk/credential-issuance-client'
import { AuthProvider } from '@affinidi-tdk/auth-provider'
import affinidi_tdk_auth_provider
import affinidi_tdk_credential_issuance_client
  1. Generate an Authorisation token to call the client using the Personal Access Token for the specific project.

Use the Affinidi CLI Token command to generate the Personal Access Token (PAT) for the Auth Provider.

If you have created the Personal Access Token (PAT) with the --key-id flag in Affinidi CLI, you must also set the keyId with the supplied value in the AuthProvider class.

// NOTE: set your variables for PAT
const privateKey = "<PAT_PRIVATE_KEY_STRING>"
const passphrase = "<PAT_KEY_PAIR_PASSPHRASE>"
const tokenId = "<PAT_ID>"
const projectId = "<PROJECT_ID>"

const authProvider = new AuthProvider({
    privateKey,
    passphrase,
    tokenId,
    projectId
})

const authConfiguration = new Configuration({
  apiKey: authProvider.fetchProjectScopedToken.bind(authProvider)
})
stats = {
  "privateKey": "<PAT_PRIVATE_KEY_STRING>",
  "passphrase": "<PAT_KEY_PAIR_PASSPHRASE>",
  "tokenId": "<PAT_ID>",
  "projectId": "<PROJECT_ID>"
}

authProvider = affinidi_tdk_auth_provider.AuthProvider(stats)

projectScopedToken = authProvider.fetch_project_scoped_token()

configuration = affinidi_tdk_credential_issuance_client.Configuration()

# Configure API key authorization: ProjectTokenAuth
configuration.api_key['ProjectTokenAuth'] = projectScopedToken
  1. Initiate the Issuance module with the authorisation header and call the client method with the credential data.

credentialTypeId is the value configured on your Credential Issuance Configuration for the Supported Schemas.

async function issueCredential() {
    const api = new IssuanceApi(authConfiguration)

    const projectId = "<Project_ID>"
    const request: StartIssuanceInput = {
    "data": [{
        "credentialTypeId": "UniversityDegree2024",
        "credentialData": {
            "first_name": "FirstName",
            "last_name": "LastName",
            "course": "Fundamentals of Decentralised Identity",
            "completion_date": "2024-01-01"
        }
    }],
    "claimMode": "TX_CODE"
    }


    const { data } = await api.startIssuance(projectId, request)

    return data
}

issueCredential()
    .then((data) => console.log(data))
    .catch((error) => console.log(error))
with affinidi_tdk_credential_issuance_client.ApiClient(configuration) as api_client:
    api_instance = affinidi_tdk_credential_issuance_client.IssuanceApi(api_client)

    projectId = "<Project_ID>"
    request_json = {
        "data": [{
            "credentialTypeId": "UniversityDegree2024",
            "credentialData": {
                "first_name": "FirstName",
                "last_name": "LastName",
                "course": "Fundamentals of Decentralised Identity",
                "completion_date": "2024-01-01"
            }
        }],
        "claimMode": "TX_CODE"
    }

    start_issuance_input = affinidi_tdk_credential_issuance_client.StartIssuanceInput.from_dict(request_json)

    api_response = api_instance.start_issuance(projectId, start_issuance_input=start_issuance_input)

The Issuance Service will return the Credential Offer URI and the Transaction Code to obtain the credential details. Your application should send this information securely to the intended user to claim the Credential Offer within the configured duration in the Issuance Configuration.

{
  "credentialOfferUri": "https://<PROJECT_ID>.apse1.issuance.affinidi.io/offer/<ISSUANCE_ID>",
  "txCode": "123456",
  "issuanceId": "<ISSUANCE_ID>",
  "expiresIn": 3600
}

Claiming the Credential Offer

To allow the recipient of the Credential Offer to claim the credential and store it on their Affinidi Vault, developers can send the claim link via email or QR code, for example. The claim link will be in the following format with the URL encoded <CREDENTIAL_OFFER_URI> value:

https://vault.affinidi.com/claim?credential_offer_uri=<CREDENTIAL_OFFER_URI>

You can use the buildClaimLink function of VaultUtils from Affinidi TDK to build a claim link.

If the Credential Offer was created with the Transaction Code (txCode), the developer must also send the Transaction Code for the user to claim the credentials.

Learn more about the Credential Issuance and how the integration works using the sample application.