Skip to main content

Documentation Index

Fetch the complete documentation index at: https://pdocs.truthstamp.ai/llms.txt

Use this file to discover all available pages before exploring further.

This documentation outlines the process of creating and verifying proofs using the Signer Service API. The flow involves multiple steps, from converting a digital asset to creating a verifiable signature.

createProof

This function orchestrates all the API calls in sequence to generate a proof.
export async function createProof(file, description) {
  const fileBase64 = await fileToBase64(file);

  let messageHashOutput = await messageHashAPI(fileBase64);
  let blindedSignature = await commitAPI(description, messageHashOutput);
  let getChallengeResult = await getChallengeAPI(blindedSignature);
  let solveChallengeResult = await solveChallengeAPI(getChallengeResult);  
  let unblindSignatureResult = await unblindSignatureAPI(solveChallengeResult);  

  return unblindSignatureResult;
}
1

Convert your digital asset/content

First, the digital asset is converted to a Base64 string.
2

Blind your Content

Call the messageHashAPI function to hash the Base64-encoded message.
3

Submit your Signing request

Use commitAPI and pass the hash and public description to create a blinded signature.
4

Make a ZK proof for Content

Retrieve a ZK challenge for the commitment signature using the getChallengeAPI.
5

Solve ZK challenge

Use the solveChallengeAPI to solve the ZK challenge.
6

Unblind the signature

Call the unblindSignatureAPI to unblind the signature.
7

Create verifiable signature

The self verifiable signature is returned as JSON.

1. fileToBase64

Purpose:

Converts a file into a base64-encoded string without the metadata portion (data:…). This is the first step before sending the file content to any API.
function fileToBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    
    reader.onload = () => resolve(reader.result.split(',')[1]);  // Extract base64 string without the metadata part
    reader.onerror = error => reject(error);
  });
}
This function is used to read a file, converting it into a Base64 string that will be sent to the messageHashAPI for hashing.

2. messageHashAPI

Purpose:

Hashes the base64-encoded file content by sending it to an API.
async function messageHashAPI(base64Data) {
  const response = await fetch('https://api.truthstamp.ai/recipient/messageHash', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': API_KEY
    },
    body: JSON.stringify({
      message: JSON.stringify(base64Data),
    }),
  });

  if (!response.ok) {
    throw new Error('Failed to call the messageHashAPI');
  }  
  return response.json();
}

3. commitAPI

Purpose:

Creates a blinded signature by sending the hashed message and a description to the API.
async function commitAPI(description, messageHashOutput) {
  const response = await fetch('https://api.truthstamp.ai/signer/commit', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': API_KEY
    },
    body: JSON.stringify({
      commonInfo: description,
      blindedMessage: messageHashOutput.messageHash,
    }),
  });

  if (!response.ok) {
    throw new Error('Failed to call the commitAPI');
  }

  return response.json();
}

4. getChallengeAPI

Purpose:

Requests a ZK challenge from the API using the blinded signature created earlier.
async function getChallengeAPI(blindedSignatureOutput) {
  const response = await fetch('https://api.truthstamp.ai/recipient/getChallenge', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': API_KEY
    },
    body: JSON.stringify({
      "signatureCommitmentString": blindedSignatureOutput.signatureCommitmentString,
      "blindedMessage": blindedSignatureOutput.blindedMessage,
      "commonInfo": blindedSignatureOutput.commonInfo,
      "publicKey": blindedSignatureOutput.publicKey
    }),
  });

  if (!response.ok) {
    throw new Error('Failed to call the getChallengeAPI');
  }

  return response.json();
}

5. solveChallengeAPI

Purpose:

Solves the ZK challenge using the challenge format returned by the previous step.
async function solveChallengeAPI(getChallengeResultOut) {
  const response = await fetch('https://api.truthstamp.ai/signer/challenge', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': API_KEY
    },
    body: JSON.stringify({
      "challengeFormat": getChallengeResultOut.challengeFormat,
      "signatureCommitmentOut": getChallengeResultOut.signatureCommitmentOut,
      "publicKey": getChallengeResultOut.publicKey,
      "blindedMessage": getChallengeResultOut.blindedMessage,
      "commonInfo": getChallengeResultOut.commonInfo
    }),
  });

  if (!response.ok) {
    throw new Error('Failed to call the solveChallengeAPI');
  }

  return response.json();
}

6. unblindSignatureAPI

Purpose:

Unblinds the signature using the ZK challenge solution recieved.
async function unblindSignatureAPI(solveChallengeResult) {
  const response = await fetch('https://api.truthstamp.ai/recipient/unblindSignature', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': API_KEY
    },
    body: JSON.stringify({
      "challengeOut": solveChallengeResult.challengeOut,
      "solutionFormat": solveChallengeResult.solutionFormat,
      "signatureCommitmentOut": solveChallengeResult.signatureCommitmentOut,
      "publicKey": solveChallengeResult.publicKey,
      "blindedMessage": solveChallengeResult.blindedMessage,
      "commonInfo": solveChallengeResult.commonInfo
    }),
  });

  if (!response.ok) {
    throw new Error('Failed to call the unblindSignature');
  }
  return response.json();
}

verifyProof

This function is used to verify the proof.
export async function verifyProof(proofData) {
  let verifySignatureResult;
  try {
    verifySignatureResult = await verifySignatureAPI(proofData);
  } catch (error) {
    return 'Invalid format';
  }
  return verifySignatureResult;
}
1

Verify Signature

Pass the proof data to the verifySignatureAPI.
2

Return Result

Return the verification result.

verifySignatureAPI

Purpose:

Verifies the signature and return true/false.
async function verifySignatureAPI(unblindSignatureResult) {
  const response = await fetch('https://api.truthstamp.ai/verifier/verifySignature', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': API_KEY
    },
    body: JSON.stringify({
      "publicKey": unblindSignatureResult.publicKey,
      "commonInfo": unblindSignatureResult.commonInfo,
      "signatureString": unblindSignatureResult.signatureString,
      "m1Hat": unblindSignatureResult.m1Hat
    }),
  });

  if (!response.ok) {
    throw new Error('Failed to call the verifySignatureAPI');
  }

  return response.json();  // Assuming the verifySignatureAPI returns JSON
}