Issue Credentials to Affinidi Vault Users
To integrate with the Credential Issuance service, you must:
Create the Schema using Schema Builder, created schema is used in the Credential Issuance to create and issue Verifiable Credentials for users to claim and store in their Affinidi Vault account
Set up a Credential Issuance Configuration to issue a Verifiable Credential.
Use the Affinidi TDK’s Credential Issuance client to enable your application to issue credentials to your users.
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.
Note on Claim Modes
If you choose to create the Credential Offer with FIXED_HOLDER
claim mode, the credential issuance requires the user’s DID value as the Holder DID (holderDid
). To get the Holder DID, your website must implement Affinidi Login to authenticate and extract the user DID value from the ID Token provided.
You can explore our Labs to learn how to integrate Affinidi Login into different programming languages and frameworks.
Otherwise, use TX_CODE
, the default claim mode where Holder DID (holderDid
) is not required.
- 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
- 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
- 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 thekeyId
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
- 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.
Glad to hear it! Please tell us how we can improve more.
Sorry to hear that. Please tell us how we can improve.
Thank you for sharing your feedback so we can improve your experience.