claim

In this tutorial, we will simulate a Claimer to make a VC issuance request to a specified Attester with the help of SDK.

Complete code example: zkid-sdk-example /src/claim-attest/claim.ts

Tutorial

  1. Initialize @noble cryptographic library and wasm;

await initCrypto();
  1. Get the DID objects of claimer and attester;

// get claimer DID object from mnemonic
const keyring = new Keyring();
const claimer = keys.fromMnemonic(
  keyring,
  process.env.CLAIMER_MNEMONIC as string,
  "ecdsa"
);

// get attester DID object from DidDocument
const attesterDidDoc = await resolver.resolve(attesterDidUrl);
const attester = fromDidDocument(attesterDidDoc);

// src/utils/resolverHelper.ts
export const resolver = new ArweaveDidResolver();

The above sample code presents the ways to recover the DID object are: through the mnemonic recovery and through the DID document recovery. The main APIs involved are:

  • fromMnemonic, which recovers the DID object by means of a mnemonic, takes as mandatory arguments a keyring and a mnemonic in the form of a string, the keyring being the structure that manages the keypair;

fromMnemonic(keyring: KeyringInstance, mnemonic: string, signingKeyType?: 'ecdsa' | 'ed25519', index?: number)
  • fromDidDocument, which recovers the DID object by means of a DID document, takes didDocuemnt as mandatory arguments. DID documents are obtained through the resolver's resolve API;

fromDidDocument(document: DidDocument, keyring?: KeyringInstance)
  1. Get ctype object from ctype hash;

const ctype: CType = await getCtypeFromHash(ctypeHash);

// src/utils/ctypeHelper.ts
export async function getCtypeFromHash(
  hash: string | undefined,
  url = process.env.BASE_URL
): Promise<CType> {
  if (hash === undefined) {
    throw new Error("ctype hash undefined !!!");
  }

  const res = await axios.get(`${url}/ctype?${qs.stringify({ id: hash })}`);
  if (res.status !== 200) {
    throw new Error(`ctype query failed ${hash}`);
  }
  const ctype: CType = res.data.data.rawData;
  return ctype;
}

In this step, ctypeHash will be used as the query parameter of the HTTP GET request to get the ctype object.

  1. Build the Raw object. In this step, we build a Raw object which is used for the subsequent construction of the RawCredential. The following explains each property of the Raw object:

    1. contents: The body of the credential;

    2. owner: claimer/holder, credential receiver;

    3. ctype: The ctype object used for this credential;

    4. hashType: Encryption algorithm type, here choose Keccak256 (we also support Blake2, Blake3, RescuePrimeOptimized and other encryption algorithms. Note: Considering that Keccak256 has the highest hash efficiency on chain, it is recommended to use Keccak256 as the hash when building Raw if your vc usage scenario does not include zk computation, otherwise use RescuePrimeOptimized hash).

const raw = new Raw({
  contents: {
    id: 9870456,
    name: "vss-claimer",
  },
  owner: claimerDidUrl,
  ctype: ctype,
  hashType: "Keccak256",
});
  1. Build the RawCredential object. In this step, we call toRawCredential API to generate RawCredential object based on the Raw object generated in the previous step. The encryption algorithm used in this step is Keccak256 by default (meanwhile, we also support other encryption algorithms, which are the same as the ones available for building Raw);

const rawCredential: RawCredential = raw.toRawCredential("Keccak256");
  1. Construct an encrypted message of type Request_Attestation using RawCredential as the message data. We will generate the encrypted message using the encryptMessage API with the following parameters:

    1. type: Message type, In VC's request mode, the message type for a claim scenario is "Request_Attestation";

    2. data: Message data, here is RawCredential;

    3. sender: Message sender's DID object, here is claimer;

    4. receiverUrl: Message receiver's keyAgreement DID URL;

    5. reply: Prefixed message id, this parameter is only used for responding to message scenarios;

    6. resolver: DID resolver.

// encrypt Request_Attestation message
const message = await encryptMessage(
  "Request_Attestation",
  rawCredential,
  claimer,
  attester.getKeyUrl("keyAgreement"),
  undefined,
  resolver
);
  1. Send the encrypted message to the server. This process initiates an HTTP POST request.

// 'message' => server => attester
await sendMessage2Server(message);

// src/utils/messageHelper.ts
export async function sendMessage2Server(
  message: any,
  templateId = -1,
  token = null,
  url = process.env.BASE_URL
): Promise<void> {
  const sendRes = await axios.post(`${url}/message`, {
    templateId,
    msg: message,
    token,
  });
  if (sendRes.status === 200) {
    console.log(`SUCCESS: send encrypted message to server`);
  } else {
    console.log(`send encrypted message response status: ${sendRes.status}`);
  }
}

Well, with the above introduction, you will learn how to use our SDK as a claimer to make a request to one of the attester you specified. So far, this is only half of the VC request mode, so let's focus on the attester's perspective and explore how to respond to a request and send a VC.

Last updated