Skip to main content

Create Credential

To create a credential, we will need four very important things.

  1. I need the schema identifier that it will reference, which will therefore mark which attribute structure it will have. In my case it will be my employee number, name and date of birth.
  2. I will need the BJJ key created for that Issuer, because when we create a credential let's remember that in order to be verifiable we need to be able to sign it and get a proof of authenticity.
  3. You should know who is going to be the Holder of this credential or rather which is the user who is going to receive this credential. This Holder must have created his own identity at the same time. For example, in the case of our employee for whom we are going to issue this credential, the following DID identifies him/her: did:polygonid:polygon:main:2q544HUegzeRpwr3V2qu9eMwgrAmF5x4E1NCPzbQc4.
  4. We will also be able to add additional metadata such as expiration date, version number, etc...

Once the credential is created we will obtain a UUID identifier. Example: 0e3199ac-8147-4c7a-938b-d33f9107dace

The most important thing is that this credential is already a Verifiable Credential (VC) because it already includes a signature proof, and therefore, this credential would already be valid to be verified.

But BLOOCK Identity's product offers a second proof, related to integrity in blockchain. The Sparse Merkle Tree proof is a proof that will be available depending on the interval time you have chosen and is related to the Issuer's state. As I have previously chosen a 60 minutes interval, it means that I will have my SMTP proof available after ~60 minutes.


import { Bloock, KeyClient, IdentityClient, DidMethod, Key } from '@bloock/sdk';

try {
// we set the API key and create a client
Bloock.setApiKey(process.env['API_KEY'] || '');
// we set de identity managed API host you have deployed
Bloock.setIdentityApiHost(process.env['IDENTITY_MANAGED_API_HOST'] || '');

// initialize the Key Client
const keyClient = new KeyClient();
// initialize the IdentityClient
const identityClient = new IdentityClient();

// we must have our Issuer Baby JubJub key identifier. Ex: 6f36448d-49f3-4b0e-aa72-6e55863302e8
const savedIssuerKey = '6f36448d-49f3-4b0e-aa72-6e55863302e8';
const loadedManagedKey = await keyClient.loadManagedKey(savedIssuerKey);

// if we don't have our Issuer entity, here you can import you Issuer from the key
const importedIssuerKey = new Key(loadedManagedKey);
const issuerMethodDID = DidMethod.PolygonID;

const importedIssuer = await identityClient.importIssuer(

// we create the credential, passing credential information
const schemaCID = 'QmadTvnNKvj2fBDgen35uAp1TfP9pSPVCNeDWw4fitqqne'; // schema identifier created before. Ex: QmadTvnNKvj2fBDgen35uAp1TfP9pSPVCNeDWw4fitqqne. REQUIRED.
const holderDID =
'did:polygonid:polygon:main:2q544HUegzeRpwr3V2qu9eMwgrAmF5x4E1NCPzbQc4'; // the DID of the Holder to whom the credential will be associated. REQUIRED.
const expiration = 4089852142; // unix timestamp when the credential will expire. REQUIRED.
const credentialVersion = 0; // credential version. By default it's set to 0. REQUIRED.

const receipt = await identityClient
.withIntegerAttribute('number', 1)
.withDecimalAttribute('salary', 3000.7)
.withStringAttribute('nif', '54688188M')
.withBooleanAttribute('previous_formation', true)
.withDateAttribute('birth_date', new Date(1999, 3, 20))
.withDateTimeAttribute('time_registered', new Date(
.withStringAttribute('country', 'spain')
.withIntegerAttribute('brother', 1)
.withDecimalAttribute('height', 1.7)

// returns a Credential entity
console.log(receipt.credentialId); // Credential identifier. It's an UUID. Ex: f1cae203-6b54-4d71-a6e4-00e73e0c45a5
console.log(receipt.credential); // Verifiable Credential, the credential entity.
console.log(receipt.credentialType); // the credential schema type associated.
} catch (e) {