Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 8 additions & 56 deletions docs/how-tos/attachments.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ TradeTrust allows you to attach files directly to your verifiable documents and

Legacy formats (for reference only):
- OpenAttestation v2: Attachments are included in the document data before wrapping
- OpenAttestation v3: Attachments are added at the root level of the document

Attachments enable you to bundle supporting files with your verifiable documents, ensuring that all related information remains together and tamper-evident.

Expand All @@ -34,12 +33,12 @@ For broad compatibility with TradeTrust, we recommend the following attachment s
| Field | Type | Description | Required | Notes |
|-------|------|-------------|----------|-------|
| `data` | string | Base64-encoded file content | Yes | Must be plain base64 string without data URL prefixes (e.g., `JVBERi0xLjQKJ...`) |
| `filename` | string | Name of the file | Yes* | Example: "invoice.pdf" (also supports `fileName` in OA v3) |
| `filename` | string | Name of the file | Yes* | Example: "invoice.pdf" |
| `mimeType` | string | MIME type of the file | Yes* | Example: "application/pdf" (also supports `type` in OA v2) |

*Required for proper rendering in TradeTrust Verification Website

This structure is preferred for new documents. However, the TradeTrust platform, particularly its decentralized renderer, is designed to be flexible and can parse attachments from older OpenAttestation (OA) v2 and v3 formats as well.
This structure is preferred for new documents. However, the TradeTrust platform, particularly its decentralized renderer, is designed to be flexible and can parse attachments from the older OpenAttestation (OA) v2 format as well.

### Important Considerations for Attachments

Expand All @@ -51,7 +50,7 @@ When working with attachments, keep these points in mind:

### Renderer Parsing and Legacy Support

The TradeTrust decentralized renderer processes attachments to extract the necessary information for display. It primarily looks for the recommended fields (`data`, `filename`, `mimeType`) but also checks for common variations found in OA v2 and OA v3 documents.
The TradeTrust decentralized renderer processes attachments to extract the necessary information for display. It primarily looks for the recommended fields (`data`, `filename`, `mimeType`) but also checks for common variations found in OA v2 documents.

The following code snippet from `decentralized-renderer-react-components/src/utils.ts` illustrates how the renderer extracts attachment details:

Expand All @@ -63,16 +62,16 @@ const attachments = vc.isSignedDocument(document)
?.map((s) => s.attachments)
?.filter(Boolean)
?.flat()
: isV2Document(document) || isV3Document(document)
: isV2Document(document)
? document.attachments
: [];
const tabsRenderedFromAttachments = (attachments || ([] as Attachment[]))
.map((attachment: Attachment, index: number) => {
return {
id: `attachment-${index}`,
// For filename, it checks for 'fileName' (common in OA v3) then 'filename' (recommended, and OA v2)
// For filename, it checks for 'fileName' then 'filename' (recommended, OA v2)
label: ((attachment as any).fileName ?? (attachment as any)?.filename) || "Unknown filename",
// For MIME type, it checks for 'type' (common in OA v2) then 'mimeType' (recommended, and OA v3)
// For MIME type, it checks for 'type' (common in OA v2) then 'mimeType' (recommended)
type: ((attachment as any).type ?? (attachment as any).mimeType) || "Unknown filetype",
// The 'data' property is used within attachmentToComponent to render the content
template: attachmentToComponent(attachment, document)!
Expand All @@ -83,8 +82,8 @@ const tabsRenderedFromAttachments = (attachments || ([] as Attachment[]))

As shown in the snippet:

- For the attachment's **name/label**, the renderer first looks for a `fileName` property (common in OA v3) and falls back to `filename` (recommended, and also used in OA v2).
- For the attachment's **type**, it first looks for a `type` property (common in OA v2) and falls back to `mimeType` (recommended, and also used in OA v3).
- For the attachment's **name/label**, the renderer first looks for a `fileName` property and falls back to `filename` (recommended, also used in OA v2).
- For the attachment's **type**, it first looks for a `type` property (common in OA v2) and falls back to `mimeType` (recommended).

This ensures that documents created with older OpenAttestation schemas remain compatible. While this flexibility is provided, new implementations should adhere to the recommended structure (`data`, `filename`, `mimeType`) for clarity and future-proofing.

Expand Down Expand Up @@ -239,53 +238,6 @@ After wrapping, the attachments will be part of the document data with salted va
```
</details>

<details>
<summary><b>OpenAttestation v3</b></summary>

For OpenAttestation v3 documents, attachments are added at the root level:

```json
{
"version": "https://schema.openattestation.com/3.0/schema.json",
"network": {
"chain": "FREE",
"chainId": "101010"
},
"credentialSubject": {
// Document data goes here
},
"attachments": [
{
"data": "JVBERi0xLjQKJdPr6eEKMSAwIG9iago8PC9UaXRsZSAoRXhhbXBsZSBQREYpCi9Qcm9kdWNlciAoT3...",
"fileName": "certificate.pdf",
"mimeType": "application/pdf"
}
],
"openAttestationMetadata": {
"template": {
"type": "EMBEDDED_RENDERER",
"name": "CHAFTA_COO",
"url": "https://generic-templates.tradetrust.io"
},
"proof": {
"type": "OpenAttestationProofMethod",
"method": "DOCUMENT_STORE",
"value": "0xA594f6e10564e87888425c7CC3910FE1c800aB0B"
},
"identityProof": {
"type": "DNS-TXT",
"identifier": "example.tradetrust.io"
}
},
"issuer": {
"id": "https://example.com",
"name": "DEMO DOCUMENT STORE",
"type": "OpenAttestationIssuer"
}
}
```
</details>

## Handling Attachments in TradeTrust Verification Website

TradeTrust's Verification Website automatically detects and displays attachments in the document viewer. Attachments appear as tabs alongside the main document view, allowing users to switch between the main document and its attachments.
Expand Down
25 changes: 0 additions & 25 deletions docs/how-tos/implementing-qr-codes.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,32 +60,8 @@ For W3C Verifiable Credentials, you need to add a `qrCode` property to your cred

For OpenAttestation documents, QR codes are implemented in the document's links property:

- In OA v3: via `credentialSubject.links.self.href`
- In OA v2: via `data.links.self.href`

<details>
<summary>View OA v3 Example</summary>

```json
{
"version": "https://schema.openattestation.com/3.0/schema.json",
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://schemata.openattestation.com/com/openattestation/1.0/OpenAttestation.v3.json"
],
"credentialSubject": {
// Document data
"links": {
"self": {
"href": "https://actions.tradetrust.io?q=%7B%22type%22%3A%22DOCUMENT%22%2C%22payload%22%3A%7B%22uri%22%3A%22https%3A%2F%2Fexample.com%2Fdocuments%2F123%22%2C%22key%22%3A%22abcdef1234567890%22%2C%22permittedActions%22%3A%5B%22STORE%22%5D%2C%22redirect%22%3A%22https%3A%2F%2Ftradetrust.io%2F%22%2C%22chainId%22%3A%22101010%22%7D%7D"
}
}
},
// Other document properties
}
```
</details>

<details>
<summary>View OA v2 Example</summary>

Expand Down Expand Up @@ -186,7 +162,6 @@ When a TradeTrust-compatible document with a QR code is loaded, the TradeTrust w

2. Extracts the QR code URL using the `getQRCodeLink` function, which checks for:
- `qrCode.uri` in W3C VC documents
- `credentialSubject.links.self.href` in OA v3 documents
- `links.self.href` in OA v2 documents

3. TradeTrust then downloads the document from the specified URI, decrypting it if necessary.
Expand Down
2 changes: 1 addition & 1 deletion docs/how-tos/verifydocument.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ The document to be verified. It can be:

#### 1) Check Document Type

- If the document is an OpenAttestation document (V2 or V3), it uses OpenAttestation verifiers.
- If the document is an OpenAttestation document (V2), it uses OpenAttestation verifiers.
- Otherwise, it is treated as a W3C Verifiable Credential, and W3C verification fragments are used.

#### 2) Build the Verification Process
Expand Down
13 changes: 4 additions & 9 deletions docs/tutorial/decentralized-renderer.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ The template repository comes with two example templates that you can use as ref

1. **`templates/examples/TemplateA`** - Demonstrates:
- Basic document rendering
- Support for both OA (OpenAttestation) V2, V3 and W3C VC document formats
- Support for both OA (OpenAttestation) V2 and W3C VC document formats
- QR code integration with `DocumentQrCode` component
- Watermark integration with `PrintWatermark` component
- Error boundary integration with `Wrapper` component
Expand All @@ -106,18 +106,15 @@ First, create a new folder for your template and define the data structure.
<summary>Create a file `src/templates/BillOfLading/types.ts`:</summary>

```ts
import { v2, v3, SignedVerifiableCredential } from "@trustvc/trustvc";
import { v2, SignedVerifiableCredential } from "@trustvc/trustvc";
import { CredentialSubject } from "@trustvc/trustvc/w3c/vc";

export type BillOfLadingSchemaV2 = v2.OpenAttestationDocument & BillOfLadingDocument;
export type BillOfLadingSchemaV3 = v3.OpenAttestationDocument & {
credentialSubject: BillOfLadingDocument;
};
export type BillOfLadingSchemaW3C = SignedVerifiableCredential & {
credentialSubject: CredentialSubject & BillOfLadingDocument;
};

export type BillOfLadingSchema = BillOfLadingSchemaV2 | BillOfLadingSchemaV3 | BillOfLadingSchemaW3C;
export type BillOfLadingSchema = BillOfLadingSchemaV2 | BillOfLadingSchemaW3C;

export interface BillOfLadingDocument {
scac: string;
Expand Down Expand Up @@ -817,16 +814,14 @@ import React from "react";
import ReactDOM from "react-dom";
import { BillOfLadingSample } from "../src/templates/BillOfLading/sample";
import { TemplateASampleV2 } from "../src/templates/examples/TemplateA/sampleV2";
import { TemplateASampleV3 } from "../src/templates/examples/TemplateA/sampleV3";
import { App } from "./app";
import "./main.css";

ReactDOM.render(
<App
documents={[
{ name: "Bill of Lading", document: BillOfLadingSample },
{ name: "Example A v2", document: TemplateASampleV2 },
{ name: "Example A v3", document: TemplateASampleV3 }
{ name: "Example A v2", document: TemplateASampleV2 }
]}
/>,
document.getElementById("root")
Expand Down
2 changes: 1 addition & 1 deletion src/components/ContractCost/hooks/useFetchGasPrice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export enum Chain {
const gasApi = {
[Chain.Ethereum]: "https://api.blocknative.com/gasprices/blockprices",
[Chain.Polygon]: "https://api.blocknative.com/gasprices/blockprices?chainid=137",
[Chain.XDC]: "https://rpc.xinfin.network/gasPrice",
[Chain.XDC]: "https://xdctraderpc.xinfin.network/",
};

const parseGasRes = (res: any) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,69 +239,6 @@ _Transferrable document requires a [`tokenRegistry`](/docs/4.x/tutorial/transfer

- The `"identityProof"` property is an object that refers to the issuer identity, please refer to [identity Proof](/docs/4.x/tutorial/verifiable-documents/advanced/document-store/configuring-dns) for more information.

#### V3 document defaults

```json
"defaults": {
"version": "https://schema.openattestation.com/3.0/schema.json",
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://schemata.openattestation.com/io/tradetrust/Invoice/1.0/invoice-context.json",
"https://schemata.openattestation.com/com/openattestation/1.0/OpenAttestation.v3.json"
],
"type": [
"VerifiableCredential",
"OpenAttestationCredential"
],
"issuanceDate": "2010-01-01T19:23:24Z",
"openAttestationMetadata": {
"template": {
"type": "EMBEDDED_RENDERER",
"name": "INVOICE",
"url": "https://generic-templates.tradetrust.io"
},
"proof": {
"type": "OpenAttestationProofMethod",
"method": "DOCUMENT_STORE",
"value": "0x49b2969bF0E4aa822023a9eA2293b24E4518C1DD",
"revocation": {
"type": "NONE"
}
},
"identityProof": {
"type": "DNS-TXT",
"identifier": "demo-tradetrust.openattestation.com"
}
},
"credentialSubject": {},
"issuer": {
"id": "https://example.com",
"name": "DEMO DOCUMENT STORE",
"type": "OpenAttestationIssuer"
}
},
```

- The value of the `"version"` property contains information about the version of the document to be created.

- The value of the `"@context"` property contain value that MUST be an ordered set where the first item is a URI with the value https://www.w3.org/2018/credentials/v1. Subsequent items in the array MUST express context information and be composed of any combination of URIs or objects. It is RECOMMENDED that each URI in the @context be one which, if dereferenced, results in a document containing machine-readable information about the @context.

- The value of the `"type"` property contains value that MUST be, or map to (through interpretation of the @context property), one or more URIs. If more than one URI is provided, the URIs MUST be interpreted as an unordered set.

- The value of the `"issuanceDate"` property MUST be a string value of a combined date-time string representing the date and time the credential becomes valid. Note that this value represents the earliest point in time at which the information associated with the credentialSubject property becomes valid.

- The value of the `"openAttestationMetadata"` properties contains information about the `"template"` and `"proof"`.

- The value of `"template"` property contains an object that refers to the custom renderer, please refer to [creating document renderer](/docs/4.x/tutorial/decentralised-renderer/).

- The value `"proof"` property contains an object with the necessary information about the `"type"` of proof, `"method"` of proof, `"value"` of the proof method and the `"revocation"` type and status of the document.

- The `"identityProof"` property is an object that refers to the issuer identity, please refer to [identity Proof](/docs/4.x/tutorial/verifiable-documents/advanced/document-store/configuring-dns) for more information.

- The value of the `"credentialSubject"` property is defined as a set of objects that contain one or more properties that are each related to a subject of the verifiable credential.

- The value of the `"issuer"` property MUST be either a URI or an object containing an id property. It is RECOMMENDED that the URI in the issuer or its id be one which, if dereferenced, results in a document containing machine-readable information about the issuer that can be used to verify the information expressed in the credential.

---

### `"schema"` property
Expand Down
12 changes: 2 additions & 10 deletions versioned_docs/version-4.x/reference/libraries/oa.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ npm i @govtechsg/open-attestation

`wrapDocuments` takes in an array of documents and returns the wrapped batch. Each document must be valid regarding the version of the schema used (see below) It computes the Merkle root of the batch and appends it to each document. This Merkle root can be published on the blockchain and queried against to prove the provenance of the document issued this way. Alternatively, the Merkle root may be signed by the document issuer's private key, which may be cryptographically verified using the issuer's public key or Ethereum account.

In the future, this function may accept a second optional parameter to specify the version of open-attestation you want to use. Currently, open-attestation will use schema 2.0. See [Additional Information](#additional-information) for information on using experimental v3.0 documents, which aim to be compatible with the W3C's data model for [Verifiable Credentials](https://www.w3.org/TR/vc-data-model/).
In the future, this function may accept a second optional parameter to specify the version of open-attestation you want to use. Currently, open-attestation will use schema 2.0.

The `wrapDocument` function is identical but accepts only one document.

Expand Down Expand Up @@ -145,13 +145,11 @@ console.log(data);

```js
import { utils } from "@govtechsg/open-attestation";
utils.isWrappedV3Document(document);
utils.isWrappedV2Document(document);
```

- `isWrappedV2Document` type guard for wrapped v2 document
- `isSignedWrappedV2Document` type guard for signed v2 document
- `isSignedWrappedV3Document` type guard for signed v3 document
- `isWrappedV3Document` type guard for wrapped v3 document
- `diagnose` tool to find out why a document is not a valid open attestation file (wrapped or signed document)

### Obfuscating data
Expand Down Expand Up @@ -192,11 +190,5 @@ You can now debug from the `vc-test-suite` folder the way you need it.
## Additional information

- Found a bug? Have a question? Want to share an idea? Reach us at our [Github repository](https://github.com/Open-Attestation/open-attestation).
- We are currently building a new version of the schema, compatible with W3C VC. This is very experimental and whatever is available for v2 documents are also available for v3 documents:
- [OA schema v3](https://schema.openattestation.com/3.0/schema.json)
- Typings: `import {v3} from "@govtechsg/open-attestation"`.
- Type guard: `utils.isWrappedV3Document`.
- Wrapping: `__unsafe__use__it__at__your__own__risks__wrapDocument` (future usage: `wrapDocument(document, {version: "open-attestation/3.0"})`
- Example docs in `tests/fixtures/v3`
- There are extra utilities available:
- Refer to the [utils](https://github.com/Open-Attestation/open-attestation/blob/master/src/shared/utils/utils.ts) component for the full list of utilities.
Loading