Tutorials

Create a DID

In order to create a Ziden DID, you need to generate a random 32-byte PrivateKey.

Random 32-byte PrivateKey

import { auth } from '@zidendev/zidenjs';
import { randomBytes } from 'crypto';

const privateKey = randomBytes(32);
const auth = await auth.newAuthFromPrivateKey(privateKey);

Then, use our TS Package to generate your own Authentication Tree, and then you can extract your Genesis ID. This Genesis ID will be your unique DID in our ecosystem.

import { auth, db, state } from '@zidendev/zidenjs';
import { randomBytes } from 'crypto';

const privateKey = randomBytes(32);
const auth = await auth.newAuthFromPrivateKey(privateKey);

// setup level DB to store trees
const authDb = smt.SMTLevelDb('/path/to/your/authDb');
const claimDb = smt.SMTLevelDb('/path/to/your/claimDb');
const claimRevDb = smt.SMTLevelDb('/path/to/your/claimRevDb');

const identity = await state.State.generateState([auth], authDb, claimDb, claimRevDb);

Use can also use BIP39 and BIP32 libs to create your own HD wallets, for example:

Request for a new Claim

Claims are issued based on the specification of registered schemas, so to request a for a new claim, the Holder need to query information of registered Issuers to find the suitable schema registry.

Each Issuer has their own list of registered Schema.

After they found the correct Schema Registry, the Holder need to provide information for the Issuer for the issuance of the Identity Claim.

The Holder will receive a unique ID for their newly created claim. They can use this to track the status of the claim, which can be one of the followings:

  • Reviewing

  • Pending

  • Active

  • Rejected

  • Waiting

Accept a Claim

Besides directly request for issuance of new claims, the Holder can also accept pre-issued claims from Issuers. This approach fits for use cases where the Issuer wants to perform batch issuance for multiple Holders.

The Holder can query all claims attached to their DID and check if there is any claim with the "Waiting" status. Then, they can use the unique ID of the claim to accept it.

Backup/Recover Claims

In order to backup user data, the Holder need encrypt their claims with a SecretKey before upload to the Backup Service to protect their data.

After finishing backup, the Holder can fetch their data from the Backup Service and decrypt to use on other devices.

Therefore, we recommend using a separated backup password or a derived key from the Holder's auth to enable seamless experience across devices.

Generate ZKP for Attestations

Services are managed by Verifiers, so to utilize their claims, the Holder need to query information of registered Verifiers to find available services.

Each Verifier has their own list of registered Service.

After they found Service they want, the Holder check if they meet the service's requirements. If yes, they should fetch all the necessary inputs for the proof generation process.

In order to generate a ZKP proof for attestation, they need to use the TS Package.

import { queryMTP, claim, auth } from '@zidendev/zidenjs';
const { newClaim, schemaHashFromBigInt, withSlotData, withIndexID } = claim;

const holderPrivateKey = // mock here
const holderAuth = await auth.newAuthFromPrivateKey(holderPrivateKey);
const query1 = {
  slotIndex: 2,
  operator: OPERATOR.LESS_THAN,
  values: [BigInt(20040101)],
  valueTreeDepth: 6,
  from: 10,
  to: 100,
  timestamp: Date.now(),
  claimSchema: BigInt(12394),
};

const slot1 = setBits(BigInt(0), query1.from, BigInt(20010101));

const claim1 = newClaim(
  schemaHashFromBigInt(query1.claimSchema),
  withSlotData(query1.slotIndex, numToBits(slot1, 32)),
  withIndexID(holderState.userID)
);

// issuer side: grant kycGenerateQueryMTPInput for holder once issued
const kycQueryMTPInput = await kycGenerateQueryMTPInput(claim1.hiRaw(), issuerState);

// issuer side: grant kycGenerateNonRevQueryMTPInput for holder when asked
const kycNonRevQueryMTPInput = await kycGenerateNonRevQueryMTPInput(claim1.getRevocationNonce(), issuerState);
// holder side: generate queryMTP proof on their claim
const witness = await holderGenerateQueryMTPWitnessWithPrivateKey(
  claim1,
  holderPrivateKey,
  holderAuth,
  BigInt(1),
  holderState,
  kycQueryMTPInput,
  kycNonRevQueryMTPInput,
  query1
);

After successfully generated a valid attestation proof, the Holder need to upload it to the Portal Service for the Verifier.

Share attestation verification results

Moreover, the Holder can also directly share the verification result of the attestation proof to others.

Resources

Last updated