Skip to main content

๐Ÿ‘ค Did

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

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

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

KILT 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 KILT blockchain. The DID creation operation requires funds from the assoicated KILT 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 Kilt = require('@kiltprotocol/sdk-js')

async function keystoreGeneration() {
const keystore = new Kilt.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 Kilt = require('@kiltprotocol/sdk-js')

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: Kilt.Did.SigningAlgorithms.Ed25519,
seed: claimerMnemonic,
})
const claimerEncryptionKeypair = await keystore.generateKeypair({
alg: Kilt.Did.EncryptionAlgorithms.NaclBox,
seed: claimerMnemonic,
})

const claimerLightDid = new Kilt.Did.LightDidDetails({
authenticationKey: {
publicKey: claimerSigningKeypair.publicKey,
type: Kilt.Did.DemoKeystore.getKeypairTypeForAlg(
claimerSigningKeypair.alg
),
},
encryptionKey: {
publicKey: claimerEncryptionKeypair.publicKey,
type: Kilt.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 Kilt = require('@kiltprotocol/sdk-js')

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

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

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

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

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

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

await Kilt.disconnect()

return { attesterFullDid, keystore }
}

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

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

await Kilt.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 kilt-rocks 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:kilt:light:014ons5NFdNeaVfxCkcXhPc9Hv2pWNR5muzuxW3iGTHUKuMnCS:oWFlomlwdWJsaWNLZXlYIBsVppuQ2fi/beBdYf50+n/36FnCjMw+KLSu3AmW9DEGZHR5cGVmeDI1NTE5

Example of a full DID Identifier: did:kilt:014ons5NFdNeaVfxCkcXhPc9Hv2pWNR5muzuxW3iGTHUKuMnCS

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!