Skip to main content

DID

Time to make a DID using the previously created accounts for the claimer and the attester.

In ProofID, there is a DID may represents an entity - for example a person, an organization or even a machine.

A ProofID Decentralised Identifier (DID) is a string uniquely identifying each ProofID user. The DID can contain multiple different keys, it can be thought of a controller account for the DID subject.

ProofID DID
  • An authentication keypair that is used to sign claims and attestations
  • An encryption keypair, used to encrypt messages between participants of the system
  • An attestation keypair, used to write ctypes and attestations on chain
  • A delegation keypair, used to write delegations on the blockchain
  • Keypairs can be replaced over time, even if the key has been compromised

There are different types of DIDs that can perform different actions, either a light or full DID.

Light DID

A light DIDs are less flexible and are suitable for lower-security use cases.

  • Sign claims and attestations with the authentication keys
  • Encrypting messages with the encryption keys

A full DID requires interaction with the ProofID blockchain. The DID creation operation requires funds from the assoicated ProofID address with enough funds to pay the transaction fees and the required deposit.

Full DID

Full DID is robust and allows for more use cases.

  • Store multiple different keys and key types
  • Has all features of a light DID
  • Write delegations on the blockchain with the key type
  • Creation of ctypes and attestations to be stored on the chain

Before the creation of a DID there needs to be a keystore.

Keystore

A keystore has multiple purposes:

  • The keystore can hold multiple DID keypairs and key types
  • The keystore stores the keys encrypted
  • The keystore can be used to encrypt and decrypt data

Code

First, the construction of the keystore.

danger

Caution the following keystore is only for demo purposes and considered unsafe.

Create a new file keystore.js and copy the following code:

const ProofID = require('@proofid/pid-ts-lib')

async function keystoreGeneration() {
const keystore = new ProofID.Did.DemoKeystore()

return keystore
}

module.exports.keystoreGeneration = keystoreGeneration

Taking the claimer and attester accounts to generate the DID and the assoicated keys.

Create a new file claimersDid.js. To generate a light DID, you will need the claimers account:

const ProofID = require('@proofid/pid-ts-lib')

async function createClaimerLightDid(keystore, claimerMnemonic) {
// replace with the claimer mnemonic
// const claimerMnemonic =
// 'gold upset segment cake universe carry demand comfort dawn invite element capital'

const claimerSigningKeypair = await keystore.generateKeypair({
alg: ProofID.Did.SigningAlgorithms.Ed25519,
seed: claimerMnemonic,
})
const claimerEncryptionKeypair = await keystore.generateKeypair({
alg: ProofID.Did.EncryptionAlgorithms.NaclBox,
seed: claimerMnemonic,
})

const claimerLightDid = new ProofID.Did.LightDidDetails({
authenticationKey: {
publicKey: claimerSigningKeypair.publicKey,
type: ProofID.Did.DemoKeystore.getKeypairTypeForAlg(
claimerSigningKeypair.alg
),
},
encryptionKey: {
publicKey: claimerEncryptionKeypair.publicKey,
type: ProofID.Did.DemoKeystore.getKeypairTypeForAlg(
claimerEncryptionKeypair.alg
),
},
})

console.log('Claimers Light DID:', claimerLightDid)

return { claimerLightDid, keystore }
}

module.exports.createClaimerLightDid = createClaimerLightDid

Create a new file attestersDid.js. To generate a full DID, you will need the claimers account and creation of the corresponding keypairs:

Don't forget you need play tokens as an Attester mention in the setup step

const ProofID = require('@proofid/pid-ts-lib')

async function createAttesterFullDid(attester, attesterMnemonic, keystore) {
await ProofID.connect()

// Signing keypair
const attesterSigningKeypair = await keystore.generateKeypair({
alg: ProofID.Did.SigningAlgorithms.Ed25519,
seed: attesterMnemonic,
})

// Encryption keypair
const attesterEncryptionKeypair = await keystore.generateKeypair({
alg: ProofID.Did.EncryptionAlgorithms.NaclBox,
seed: attesterMnemonic,
})

const keys = {
authentication: {
publicKey: attesterSigningKeypair.publicKey,
type: ProofID.Did.DemoKeystore.getKeypairTypeForAlg(
attesterSigningKeypair.alg
),
},
keyAgreement: {
publicKey: attesterEncryptionKeypair.publicKey,
type: ProofID.Did.DemoKeystore.getKeypairTypeForAlg(
attesterEncryptionKeypair.alg
),
},
capabilityDelegation: {
publicKey: attesterSigningKeypair.publicKey,
type: ProofID.Did.DemoKeystore.getKeypairTypeForAlg(
attesterSigningKeypair.alg
),
},
assertionMethod: {
publicKey: attesterSigningKeypair.publicKey,
type: ProofID.Did.DemoKeystore.getKeypairTypeForAlg(
attesterSigningKeypair.alg
),
},
}

const { extrinsic, did } = await ProofID.Did.DidUtils.writeDidFromPublicKeys(
keystore,
attester.address,
keys
)

if (await ProofID.Did.DidChain.queryById(attester.address)) {
// The DID has already been written on-chain
const attesterFullDid = await ProofID.Did.DefaultResolver.resolveDoc(did)
console.log('Attesters Full DID fetched from the chain:', attesterFullDid)

await ProofID.disconnect()

return { attesterFullDid, keystore }
}

await ProofID.BlockchainUtils.signAndSubmitTx(extrinsic, attester, {
reSign: true,
resolveOn: ProofID.BlockchainUtils.IS_FINALIZED,
})

const attesterFullDid = await ProofID.Did.DefaultResolver.resolveDoc(did)
console.log('Attesters Full DID:', attesterFullDid)

await ProofID.disconnect()

return { attesterFullDid, keystore }
}

module.exports.createAttesterFullDid = createAttesterFullDid

Now its time to make the DID's.

Run

The keystore should be instantiated once and used within the workshop passing it through the different stages of the workshop. Import the keystore.js, claimersDid.js and attestersDid.js into the index.js. Run this command in your terminal, still within your pid-app directory:

node index.js

Your output should look like this (but it won't be identical since the DIDs are constructed from your account):

Example of a light DID Identifier: did:pid:light:015CKRo6bqfDKFUjXvUiNXBMGmKJnFSXBpCSN34jkZfXZzZi5X:z1Ac9CMtYCTRWjetJfJqJoV7FcNo4XgLHy1LnQvzUVwcYoXszy1AYjPyqZDr1G5RMjBdSiA6APyDGNzKSqyk4s2

Example of a full DID Identifier: did:pid:015CKRo6bqfDKFUjXvUiNXBMGmKJnFSXBpCSN34jkZfXZzZi5X

The keystore and the two DID's need to be stored for re-use.

Well done - You've successfully generated a light and full DID!