Skip to main content

Link files to credentials

In many cases, verifiable credentials need to include additional supporting documents, such as PDFs, images, or other file types. The Truvity SDK allows you to securely link external files to your credentials, enriching the data and providing further evidence to support the claims in the credential.

Linking files to credentials is particularly useful for:

  • Digitizing Existing Documents (Creating Digital Twins): Transform physical documents into verifiable credentials by attaching their digital versions (e.g., scans or electronic copies) to a credential. This process creates a “digital twin,” allowing the original document to be securely shared and verified.
  • Supporting Documentation: Attach evidence to a credential, such as a scanned certificate, diploma, or ID card.
  • Rich Data Representations: Provide additional context or resources that help verifiers understand the credential more deeply.
  • Compliance: Attach regulatory documents or contracts required by specific industries (e.g., legal agreements or compliance certificates).

Upload a file

Before you link a file to a credential, you need to upload the file blob to the server. This section outlines the process for uploading a file to the Truvity API and creating a lightweight file representation (a file resource) using the createLinkedFile() method.

Read the file

Option 1: Use a Buffer

This method is straightforward, but not recommended for large files, as it can exhaust available memory.

For example:

const fileBlob = Buffer.from('hello world', 'utf8')

Option 2: Use a Readable Stream

This method creates a pointer to the file location without immediately loading the file into memory. This is ideal for large files, as data is read incrementally when needed.

For example:

import fs from 'fs';

const fileBlob = fs.createReadStream('path/to/your/file.txt')

Upload the file and create a file resource

Use the createLinkedFile() method to upload the file to the API and create a file resource, which is a lightweight SDK representation. This intermediate representation:

  • Provides access to the original file resource.
  • Allows you to download the uploaded file.
  • Can be linked to a draft.
const uploadedFile = await client.createLinkedFile(fileBlob);
note

Under the hood, the createLinkedFile() method utilizes a combination of fileUpload and fileCreate API calls. If you do not want to use the createLinkedFile() method, you need to do the following to create a file:

  1. Reserve space for the file in S3 using fileUpload().
  2. Upload the file to the reserved location in S3 using the programming language's HTTP request functionality.
  3. Finalize the upload and creates the API resource using fileCreate().

Create user-defined types (UDTs) definition for linked files

To link a file to a credential, you first need to create a user-defined types (UDTs) definition for the credential. Use the decorator and the LinkedFile custom claim type:

@VcContext({ name: "ClaimsModelExample", namespace: "https://www.w3.org/ns/credentials/issuer-dependent" })
class ClaimsModelExample {
@VcLinkedFileClaim
@VcNotEmptyClaim
fileAttachment!: LinkedFile;
}

After defining the UDT, create a draft that includes the uploaded file as a claim:

const claimsModelExample = await client.createVcDecorator(ClaimsModelExample);

const claimsModelExampleDraft = await claimsModelExample.create({
claims: {
fileAttachment: uploadedFile,
},
});

File immutability and deduplication logic

Before a file is stored, the API ensures immutability and deduplication by following these steps:

  1. Calculate the file hash - A multihash is computed based on the file content to create a unique fingerprint.

  2. Validate file id (if provided) – If a previously created file id is included in the request body, the system:

  • Checks whether another file already exists with the same id.
  • If a different file is found with the same id, a 409 ConflictResource error is returned.
  1. Generate file id (if missing) – If no file id is provided, the system generates one automatically.
note

This is required for DIDComm-based file exchanges.

  1. Deduplication Check – The system prevents creating resource duplicates by searching for matching files based on file hash, metadata (filename and content type), and file id when provided.

  2. Return existing file (if duplicate) – If an identical file already exists, the system returns it instead of creating a new resource.

  3. Store the new file (if unique) – If no duplicate is found, the file is stored as a new resource.

Further reading