Skip to content

Sdk v1.0 Tamplate #335

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import * as Kilt from '@kiltprotocol/sdk-js'

export async function createDriversLicenseCType(
creator: Kilt.DidUri,
submitterAccount: Kilt.KiltKeyringPair,
signCallback: Kilt.SignExtrinsicCallback
): Promise<Kilt.ICType> {
const api = Kilt.ConfigService.get('api')

// Create a new CType definition.
const ctype = Kilt.CType.fromProperties(`Drivers License by ${creator}`, {
name: {
type: 'string'
},
age: {
type: 'integer'
},
id: {
type: 'string'
}
})

// Generate a creation tx.
const encodedCtype = Kilt.CType.toChain(ctype)
const ctypeCreationTx = api.tx.ctype.add(encodedCtype)
// Sign it with the right DID key.
const authorizedCtypeCreationTx = await Kilt.Did.authorizeTx(
creator,
ctypeCreationTx,
signCallback,
submitterAccount.address
)
// Submit the creation tx to the KILT blockchain
// using the KILT account specified in the creation operation.
await Kilt.Blockchain.signAndSubmitTx(
authorizedCtypeCreationTx,
submitterAccount
)

return ctype
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import * as Kilt from '@kiltprotocol/sdk-js'

export async function fetchCType(
ctypeId: Kilt.ICType['$id']
): Promise<Kilt.CType.ICTypeDetails> {
// Example CType ID: kilt:ctype:0x329a2a5861ea63c250763e5e4c4d4a18fe4470a31e541365c7fb831e5432b940
return Kilt.CType.fetchFromChain(ctypeId)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as Kilt from '@kiltprotocol/sdk-js'

export function requestAttestation(
claimer: Kilt.DidDocument,
ctype: Kilt.ICType
): Kilt.ICredential {
// The claimer generates the claim they would like to get attested.
const claim = Kilt.Claim.fromCTypeAndClaimContents(
ctype,
{
name: 'Alice',
age: 29,
id: '123456789987654321'
},
claimer.uri
)

const credential = Kilt.Credential.fromClaim(claim)
return credential
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import * as Kilt from '@kiltprotocol/sdk-js'

export async function createAttestation(
attester: Kilt.DidUri,
submitterAccount: Kilt.KiltKeyringPair,
signCallback: Kilt.SignExtrinsicCallback,
credential: Kilt.ICredential
): Promise<void> {
const api = Kilt.ConfigService.get('api')

// Create an attestation object and write its root hash on the chain
// using the provided attester's full DID.
const { cTypeHash, claimHash, delegationId } =
Kilt.Attestation.fromCredentialAndDid(credential, attester)

// Write the attestation info on the chain.
const attestationTx = api.tx.attestation.add(
claimHash,
cTypeHash,
delegationId
)
const authorizedAttestationTx = await Kilt.Did.authorizeTx(
attester,
attestationTx,
signCallback,
submitterAccount.address
)
await Kilt.Blockchain.signAndSubmitTx(
authorizedAttestationTx,
submitterAccount
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import * as Kilt from '@kiltprotocol/sdk-js'

export async function createPresentation(
credential: Kilt.ICredential,
signCallback: Kilt.SignCallback,
selectedAttributes?: string[],
challenge?: string
): Promise<Kilt.ICredentialPresentation> {
// Create a presentation with only the specified fields revealed, if specified.
return Kilt.Credential.createPresentation({
credential,
signCallback,
selectedAttributes,
challenge
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import * as Kilt from '@kiltprotocol/sdk-js'

export async function verifyPresentation(
presentation: Kilt.ICredentialPresentation,
{
challenge,
trustedAttesterUris = []
}: {
challenge?: string
trustedAttesterUris?: Kilt.DidUri[]
} = {}
): Promise<void> {
// Verify the presentation with the provided challenge.
const { revoked, attester } = await Kilt.Credential.verifyPresentation(
presentation,
{ challenge }
)

if (revoked) {
throw new Error("Credential has been revoked and hence it's not valid.")
}
if (!trustedAttesterUris.includes(attester)) {
throw `Credential was issued by ${attester} which is not in the provided list of trusted attesters: ${trustedAttesterUris}.`
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import * as Kilt from '@kiltprotocol/sdk-js'

export async function revokeCredential(
attester: Kilt.DidUri,
submitterAccount: Kilt.KiltKeyringPair,
signCallback: Kilt.SignExtrinsicCallback,
credential: Kilt.ICredential,
shouldRemove = false
): Promise<void> {
const api = Kilt.ConfigService.get('api')

const tx = shouldRemove
? // If the attestation is to be removed, create a `remove` tx,
// which revokes and removes the attestation in one go.
api.tx.attestation.remove(credential.rootHash, null)
: // Otherwise, simply revoke the attestation but leave it on chain.
// Hence, the storage is not cleared and the deposit not returned.
api.tx.attestation.revoke(credential.rootHash, null)

const authorizedTx = await Kilt.Did.authorizeTx(
attester,
tx,
signCallback,
submitterAccount.address
)

// Submit the right tx to the KILT blockchain.
await Kilt.Blockchain.signAndSubmitTx(authorizedTx, submitterAccount)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import * as Kilt from '@kiltprotocol/sdk-js'

export async function reclaimAttestationDeposit(
submitterAddress: Kilt.KiltKeyringPair,
credential: Kilt.ICredential
): Promise<void> {
const api = Kilt.ConfigService.get('api')

// Generate the tx to claim the deposit back.
const depositReclaimTx = api.tx.attestation.reclaimDeposit(
credential.rootHash
)

// Submit the revocation tx to the KILT blockchain.
await Kilt.Blockchain.signAndSubmitTx(depositReclaimTx, submitterAddress)
}
104 changes: 104 additions & 0 deletions code_examples/sdk_examples/src/v1/core_features/claiming/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import * as Kilt from '@kiltprotocol/sdk-js'

import { createCompleteFullDid } from '../did/05_full_did_complete'
import { createSimpleLightDid } from '../did/01_light_did_simple'

import { createAttestation } from './04_create_attestation'
import { createDriversLicenseCType } from './01_create_ctype'
import { createPresentation } from './05_create_presentation'
import { fetchCType } from './02_fetch_ctype'
import { reclaimAttestationDeposit } from './08_reclaim_attestation_deposit'
import { requestAttestation } from './03_request_attestation'
import { revokeCredential } from './07_revoke_credential'
import { verifyPresentation } from './06_verify_presentation'

import { generateKeypairs } from '../utils/generateKeypairs'

export async function runAll(
submitterAccount: Kilt.KiltKeyringPair
): Promise<void> {
console.log('Running claiming flow...')
const claimerAuthKey = generateKeypairs().authentication
const claimerLightDid = createSimpleLightDid({
authentication: claimerAuthKey as Kilt.NewLightDidVerificationKey
})

const attersterKeys = generateKeypairs()
const attesterFullDid = await createCompleteFullDid(
submitterAccount,
attersterKeys,
async ({ data }) => ({
signature: attersterKeys.authentication.sign(data),
keyType: attersterKeys.authentication.type
})
)

console.log('1 claming) Create CType')
const ctype = await createDriversLicenseCType(
attesterFullDid.uri,
submitterAccount,
async ({ data }) => ({
signature: attersterKeys.assertionMethod.sign(data),
keyType: attersterKeys.assertionMethod.type
})
)
console.log('2 claiming) Fetch CType')
const ctypeDetails = await fetchCType(ctype.$id)
if (!ctypeDetails) {
throw new Error(
'Could not retrieve CType details of a CType that was just created.'
)
}
console.log('Retrieved CType details: ', ctypeDetails)
console.log('3 claiming) Create credential')
const credential = requestAttestation(claimerLightDid, ctype)
console.log('4 claiming) Create attestation and credential')
await createAttestation(
attesterFullDid.uri,
submitterAccount,
async ({ data }) => ({
signature: attersterKeys.assertionMethod.sign(data),
keyType: attersterKeys.assertionMethod.type
}),
credential
)
console.log('5 claiming) Create selective disclosure presentation')
const presentation = await createPresentation(
credential,
async ({ data }) => ({
signature: claimerAuthKey.sign(data),
keyType: claimerAuthKey.type,
keyUri: `${claimerLightDid.uri}${claimerLightDid.authentication[0].id}`
}),
['name', 'id']
)
console.log('6 claiming) Verify selective disclosure presentation')
await verifyPresentation(presentation, {
trustedAttesterUris: [attesterFullDid.uri]
})
console.log('7.1 claiming) Revoke credential')
await revokeCredential(
attesterFullDid.uri,
submitterAccount,
async ({ data }) => ({
signature: attersterKeys.assertionMethod.sign(data),
keyType: attersterKeys.assertionMethod.type
}),
credential,
false
)
console.log(
'7.2 claiming) Presentation should fail to verify after revocation'
)
try {
await verifyPresentation(presentation, {
trustedAttesterUris: [attesterFullDid.uri]
})
throw new Error('Error: verification should fail after revocation')
// eslint-disable-next-line no-empty
} catch {}
console.log('8 claiming) Reclaim attestation deposit')
await reclaimAttestationDeposit(submitterAccount, credential)

console.log('Claiming flow completed!')
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import * as Kilt from '@kiltprotocol/sdk-js'

import { mnemonicGenerate } from '@polkadot/util-crypto'

export function generateKeypairs(mnemonic = mnemonicGenerate()): {
authentication: Kilt.KiltKeyringPair
keyAgreement: Kilt.KiltEncryptionKeypair
assertionMethod: Kilt.KiltKeyringPair
capabilityDelegation: Kilt.KiltKeyringPair
} {
const authentication = Kilt.Utils.Crypto.makeKeypairFromUri(mnemonic)

const assertionMethod = Kilt.Utils.Crypto.makeKeypairFromUri(mnemonic)

const capabilityDelegation = Kilt.Utils.Crypto.makeKeypairFromUri(mnemonic)

const keyAgreement = Kilt.Utils.Crypto.makeEncryptionKeypairFromSeed(
Kilt.Utils.Crypto.mnemonicToMiniSecret(mnemonic)
)

return {
authentication: authentication,
keyAgreement: keyAgreement,
assertionMethod: assertionMethod,
capabilityDelegation: capabilityDelegation
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import * as Kilt from '@kiltprotocol/sdk-js'

export function createSimpleLightDid({
authentication
}: {
authentication: Kilt.NewLightDidVerificationKey
}): Kilt.DidDocument {
// Create a light DID from the generated authentication key.
const lightDID = Kilt.Did.createLightDidDocument({
authentication: [authentication]
})
console.log(lightDID.uri)

return lightDID
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import * as Kilt from '@kiltprotocol/sdk-js'

export function createCompleteLightDid({
authentication,
keyAgreement
}: {
authentication: Kilt.NewLightDidVerificationKey
keyAgreement: Kilt.NewDidEncryptionKey
}): Kilt.DidDocument {
// Example service for the DID.
const service: Kilt.DidServiceEndpoint[] = [
{
id: '#my-service',
type: ['KiltPublishedCredentialCollectionV1'],
serviceEndpoint: ['http://example.domain.org']
}
]

// Create the KILT light DID with the information generated.
const lightDID = Kilt.Did.createLightDidDocument({
authentication: [authentication],
keyAgreement: [keyAgreement],
service
})
console.log(lightDID.uri)

return lightDID
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import * as Kilt from '@kiltprotocol/sdk-js'

export async function migrateLightDid(
lightDid: Kilt.DidDocument,
submitterAccount: Kilt.KiltKeyringPair,
signCallback: Kilt.SignExtrinsicCallback
): Promise<Kilt.DidDocument> {
const api = Kilt.ConfigService.get('api')

// Generate the DID migration tx.
const migrationTx = await Kilt.Did.getStoreTx(
lightDid,
submitterAccount.address,
signCallback
)

// The tx can then be submitted by the authorized account as usual.
await Kilt.Blockchain.signAndSubmitTx(migrationTx, submitterAccount)

// The new information is fetched from the blockchain and returned.
const migratedFullDidUri = Kilt.Did.getFullDidUri(lightDid.uri)
const encodedUpdatedDidDetails = await api.call.did.query(
Kilt.Did.toChain(migratedFullDidUri)
)
return Kilt.Did.linkedInfoFromChain(encodedUpdatedDidDetails).document
}
Loading