Aqua ProtocolAqua Protocol
Aqua Protocol
Aqua ProtocolOpen-source cryptographic trust infrastructure for the AI era — verifiable identity, access control, and tamper-proof provenance.

Documentation

ConceptsAqua Protocol v3Schema ReferenceTooling & SDK

Documentation

ConceptsAqua Protocol v3Schema ReferenceTooling & SDK
Docs
Tooling & SDK

Tooling & SDK

Aqua JS SDK API reference and usage guide

9 min read

Aqua Protocol v3 - Tooling & SDK

The Aqua JS SDK (aqua-js-sdk) is a comprehensive TypeScript library for working with Aqua Protocol v3. It provides a complete API for creating, signing, witnessing, and verifying revision chains across multiple platforms.

Installation

Code
bash
1npm install aqua-js-sdk

Platform-Specific Imports

Code
typescript
1// Node.js (default)
2import Aquafier from 'aqua-js-sdk';
3 
4// Web Browser
5import Aquafier from 'aqua-js-sdk/web';
6 
7// React Native
8import Aquafier from 'aqua-js-sdk/react-native';

Core API

Aquafier Class

The main class providing all Aqua Protocol operations.

Constructor

Code
typescript
1const aquafier = new Aquafier();

No configuration needed for initialization.


Creating Revisions

createGenesisRevision()

Creates the first revision in a new AquaTree.

Signature:

Code
typescript
1async createGenesisRevision(
2 fileObject: FileObject,
3 isForm?: boolean,
4 enableContent?: boolean,
5 enableScalar?: boolean
6): Promise<Result<AquaOperationData, LogData[]>>

Parameters:

  • fileObject: File data to create revision from
  • isForm: If true, creates form revision (default: false)
  • enableContent: Include file content in revision (default: false)
  • enableScalar: Use scalar method instead of tree (default: true)

Returns:

  • Success: AquaOperationData with new AquaTree
  • Failure: Array of error logs

Example:

Code
typescript
1const fileObject: FileObject = {
2 fileName: "contract.pdf",
3 fileContent: pdfBuffer, // Uint8Array or string
4 path: "/documents/contract.pdf"
5};
6 
7const result = await aquafier.createGenesisRevision(fileObject);
8 
9if (result.isErr) {
10 result.data.logData.forEach(log => console.error(log));
11 return;
12}
13 
14const aquaTree = result.data.aquaTree;

createNewRevision()

Adds a new file/form revision to an existing AquaTree.

Signature:

Code
typescript
1async createNewRevision(
2 aquaTree: AquaTree,
3 fileObject: FileObject,
4 isForm?: boolean,
5 enableContent?: boolean,
6 enableScalar?: boolean
7): Promise<Result<AquaOperationData, LogData[]>>

Example:

Code
typescript
1const result = await aquafier.createNewRevision(
2 existingAquaTree,
3 updatedFileObject,
4 false, // not a form
5 false, // don't embed content
6 true // use scalar method
7);

Signing Revisions

signRevision()

Signs the latest revision in an AquaTree.

Signature:

Code
typescript
1async signRevision(
2 aquaTree: AquaTree,
3 signType: SignType,
4 credentials?: CredentialsData,
5 inlineOptions?: InlineSignerOptions
6): Promise<Result<AquaOperationData, LogData[]>>

Parameters:

  • signType: One of "cli", "metamask", "did", "p12", "inline"
  • credentials: Credentials for CLI, DID, or P12 signing
  • inlineOptions: Pre-computed signature for inline mode

Sign Types:

CLI Signing

Uses BIP39 mnemonic to derive wallet and sign.

Code
typescript
1const credentials: CredentialsData = {
2 mnemonic: "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
3 // ... other fields
4};
5 
6const result = await aquafier.signRevision(
7 aquaTree,
8 "cli",
9 credentials
10);
MetaMask Signing

Opens MetaMask for user to sign (browser only).

Code
typescript
1const result = await aquafier.signRevision(
2 aquaTree,
3 "metamask"
4);

React Native MetaMask:

Code
typescript
1const result = await aquafier.signRevision(
2 aquaTree,
3 "metamask",
4 undefined,
5 {
6 deepLinkUrl: "metamask://",
7 callbackUrl: "myapp://metamask-callback",
8 onDeepLinkReady: (url) => {
9 // Open MetaMask app
10 Linking.openURL(url);
11 }
12 }
13);
DID Signing

Signs with Decentralized Identifier.

Code
typescript
1const credentials: CredentialsData = {
2 did_key: "your-did-key-here",
3 // ... other fields
4};
5 
6const result = await aquafier.signRevision(
7 aquaTree,
8 "did",
9 credentials
10);
P12 Certificate Signing

Signs with P12 certificate.

Code
typescript
1const credentials: CredentialsData = {
2 p12_password: "certificate-password",
3 p12_content: "base64-encoded-p12-content",
4 // ... other fields
5};
6 
7const result = await aquafier.signRevision(
8 aquaTree,
9 "p12",
10 credentials
11);
Inline Signing

Use pre-computed signature.

Code
typescript
1const inlineOptions: InlineSignerOptions = {
2 walletAddress: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb8",
3 signature: "0x8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f..."
4};
5 
6const result = await aquafier.signRevision(
7 aquaTree,
8 "inline",
9 undefined,
10 inlineOptions
11);

Witnessing Revisions

witnessRevision()

Timestamps a revision via blockchain or TSA.

Signature:

Code
typescript
1async witnessRevision(
2 aquaTree: AquaTree,
3 witnessType: WitnessType,
4 witnessConfig: WitnessConfig,
5 credentials?: CredentialsData,
6 witnessPlatform?: WitnessPlatformType,
7 inlineOptions?: InlineWitnessOptions
8): Promise<Result<AquaOperationData, LogData[]>>

Parameters:

  • witnessType: "eth", "nostr", or "tsa"
  • witnessConfig: Network and contract configuration
  • credentials: Credentials for signing transaction
  • witnessPlatform: "cli" or "metamask" (Ethereum only)
  • inlineOptions: Pre-computed transaction (inline mode)

Ethereum Witnessing

Configuration:

Code
typescript
1const witnessConfig: WitnessConfig = {
2 witnessEventVerificationHash: latestRevisionHash,
3 witnessNetwork: "sepolia", // or "mainnet", "holesky"
4 smartContractAddress: "0x5FbDB2315678afecb367f032d93F642f64180aa3"
5};
6 
7const credentials: CredentialsData = {
8 mnemonic: "your mnemonic here",
9 // ...
10};

CLI Method (uses mnemonic):

Code
typescript
1const result = await aquafier.witnessRevision(
2 aquaTree,
3 "eth",
4 witnessConfig,
5 credentials,
6 "cli"
7);

MetaMask Method (prompts user):

Code
typescript
1const result = await aquafier.witnessRevision(
2 aquaTree,
3 "eth",
4 witnessConfig,
5 undefined,
6 "metamask"
7);

Nostr Witnessing

Code
typescript
1const witnessConfig: WitnessConfig = {
2 witnessEventVerificationHash: latestRevisionHash,
3 witnessNetwork: "sepolia", // not used for Nostr
4 smartContractAddress: "" // not used for Nostr
5};
6 
7const credentials: CredentialsData = {
8 nostr_sk: "your-nostr-secret-key",
9 // ...
10};
11 
12const result = await aquafier.witnessRevision(
13 aquaTree,
14 "nostr",
15 witnessConfig,
16 credentials
17);

TSA Witnessing

Code
typescript
1const result = await aquafier.witnessRevision(
2 aquaTree,
3 "tsa",
4 witnessConfig
5);

Linking Revisions

linkRevision()

Creates a link revision connecting to other AquaTrees.

Signature:

Code
typescript
1async linkRevision(
2 aquaTree: AquaTree,
3 linkedAquaTrees: AquaTree[],
4 linkType?: string
5): Promise<Result<AquaOperationData, LogData[]>>

Example:

Code
typescript
1const result = await aquafier.linkRevision(
2 mainAquaTree,
3 [dependency1Tree, dependency2Tree, dependency3Tree],
4 "dependencies"
5);

Verification

verifyRevisionChain()

Verifies an entire AquaTree chain.

Signature:

Code
typescript
1async verifyRevisionChain(
2 aquaTree: AquaTree,
3 credentials?: CredentialsData
4): Promise<VerificationGraphData>

Parameters:

  • aquaTree: Tree to verify
  • credentials: Optional, for Ethereum witness lookup

Returns:

  • VerificationGraphData: Graph structure with verification results

Example:

Code
typescript
1const verificationResult = await aquafier.verifyRevisionChain(aquaTree, credentials);
2 
3// Check overall success
4if (verificationResult.isValidationSuccessful) {
5 console.log("✓ Chain is valid");
6} else {
7 console.log("✗ Chain validation failed");
8}
9 
10// Traverse verification graph
11function printResults(node: VerificationGraphData, depth = 0) {
12 const indent = " ".repeat(depth);
13 const status = node.isValidationSuccessful ? "✓" : "✗";
14 console.log(`${indent}${status} ${node.revisionType}`);
15 
16 node.verificationGraphData.forEach(child => printResults(child, depth + 1));
17}
18 
19printResults(verificationResult);

verifyFormRevision()

Verifies form-specific data.

Signature:

Code
typescript
1async verifyFormRevision(
2 aquaTree: AquaTree,
3 formData: FormData
4): Promise<FormVerificationResponseData>

Utility Methods

removeLastRevision()

Removes the most recent revision from an AquaTree.

Signature:

Code
typescript
1removeLastRevision(
2 aquaTree: AquaTree
3): Result<AquaOperationData, LogData[]>

Example:

Code
typescript
1const result = aquafier.removeLastRevision(aquaTree);
2 
3if (result.isOk) {
4 const updatedTree = result.data.aquaTree;
5 console.log("Revision removed successfully");
6}

checkIfFileAlreadyNotarized()

Checks if a file has already been notarized.

Signature:

Code
typescript
1checkIfFileAlreadyNotarized(
2 aquaTree: AquaTree,
3 fileObject: FileObject
4): boolean

fetchFilesToBeRead()

Gets list of files that need content loaded.

Signature:

Code
typescript
1fetchFilesToBeRead(aquaTree: AquaTree): string[]

Type Reference

Core Types

Code
typescript
1interface FileObject {
2 fileName: string
3 fileContent: string | AquaTree | Uint8Array | Record<string, string> | object
4 path: string
5 fileSize?: number
6}
7 
8interface AquaTree {
9 revisions: Revisions
10 file_index: FileIndex
11 tree?: RevisionTree
12 treeMapping?: TreeMapping
13}
14 
15interface Revision {
16 previous_verification_hash: string
17 local_timestamp: string
18 revision_type: RevisionType
19 version: string
20 // ... type-specific fields
21}
22 
23type RevisionType = "file" | "witness" | "signature" | "form" | "link"
24type SignType = "metamask" | "cli" | "did" | "p12" | "inline"
25type WitnessType = "tsa" | "eth" | "nostr"
26type WitnessNetwork = "sepolia" | "mainnet" | "holesky"

Result Type

Code
typescript
1type Result<T, E> =
2 | { isOk: true; isErr: false; data: T }
3 | { isOk: false; isErr: true; data: E }

Configuration Types

Code
typescript
1interface CredentialsData {
2 mnemonic: string
3 nostr_sk: string
4 did_key: string
5 alchemy_key: string
6 witness_eth_network: string
7 witness_method: string
8 p12_password?: string
9 p12_content?: string
10}
11 
12interface WitnessConfig {
13 witnessEventVerificationHash: string
14 witnessNetwork: WitnessNetwork
15 smartContractAddress: string
16}

Platform-Specific Notes

Node.js

Full functionality available:

  • All signing methods
  • All witnessing methods
  • File system access
  • HTTP server for MetaMask callback
Code
typescript
1import Aquafier from 'aqua-js-sdk';
2import fs from 'fs';
3 
4const aquafier = new Aquafier();
5 
6// Read file from disk
7const fileContent = fs.readFileSync('document.pdf');
8 
9const fileObject = {
10 fileName: 'document.pdf',
11 fileContent: fileContent,
12 path: './document.pdf'
13};

Web Browser

Most functionality available:

  • MetaMask signing (primary method)
  • DID signing
  • Ethereum witnessing via MetaMask
  • Nostr, TSA witnessing

Limitations:

  • No P12 signing (requires file system)
  • No CLI signing with mnemonic (security risk in browser)
Code
typescript
1import Aquafier from 'aqua-js-sdk/web';
2 
3const aquafier = new Aquafier();
4 
5// File from input element
6const file = document.getElementById('fileInput').files[0];
7const arrayBuffer = await file.arrayBuffer();
8 
9const fileObject = {
10 fileName: file.name,
11 fileContent: new Uint8Array(arrayBuffer),
12 path: file.name
13};

React Native

Most functionality with platform adaptations:

  • MetaMask via deep linking
  • DID signing
  • Limited witnessing

Limitations:

  • No local HTTP server
  • MetaMask requires custom deep linking
  • File system needs react-native-fs
Code
typescript
1import Aquafier from 'aqua-js-sdk/react-native';
2import RNFS from 'react-native-fs';
3 
4const aquafier = new Aquafier();
5 
6// Read file
7const fileContent = await RNFS.readFile(filePath, 'base64');
8 
9const fileObject = {
10 fileName: 'document.pdf',
11 fileContent: Buffer.from(fileContent, 'base64'),
12 path: filePath
13};

Complete Workflow Examples

Document Notarization

Code
typescript
1// 1. Create genesis
2const fileObject: FileObject = {
3 fileName: "contract.pdf",
4 fileContent: pdfBuffer,
5 path: "/contracts/contract.pdf"
6};
7 
8let result = await aquafier.createGenesisRevision(fileObject);
9let aquaTree = result.data.aquaTree;
10 
11// 2. Sign with CLI
12const credentials: CredentialsData = {
13 mnemonic: process.env.MNEMONIC,
14 // ... other fields
15};
16 
17result = await aquafier.signRevision(aquaTree, "cli", credentials);
18aquaTree = result.data.aquaTree;
19 
20// 3. Witness to Ethereum
21const witnessConfig: WitnessConfig = {
22 witnessEventVerificationHash: Object.keys(aquaTree.revisions)[Object.keys(aquaTree.revisions).length - 1],
23 witnessNetwork: "sepolia",
24 smartContractAddress: "0x5FbDB2315678afecb367f032d93F642f64180aa3"
25};
26 
27result = await aquafier.witnessRevision(
28 aquaTree,
29 "eth",
30 witnessConfig,
31 credentials,
32 "cli"
33);
34aquaTree = result.data.aquaTree;
35 
36// 4. Save
37fs.writeFileSync('contract.aqua.json', JSON.stringify(aquaTree, null, 2));

Multi-Party Approval

Code
typescript
1// Party 1: Create and sign
2let result = await aquafier.createGenesisRevision(fileObject);
3let aquaTree = result.data.aquaTree;
4 
5result = await aquafier.signRevision(aquaTree, "cli", party1Credentials);
6aquaTree = result.data.aquaTree;
7 
8// Send aquaTree to Party 2
9 
10// Party 2: Add signature
11result = await aquafier.signRevision(aquaTree, "metamask");
12aquaTree = result.data.aquaTree;
13 
14// Send back to Party 1
15 
16// Party 1: Witness
17result = await aquafier.witnessRevision(
18 aquaTree,
19 "eth",
20 witnessConfig,
21 party1Credentials,
22 "cli"
23);
24aquaTree = result.data.aquaTree;

Form Submission with Verification

Code
typescript
1// 1. Create form genesis
2const formData = {
3 name: "John Doe",
4 email: "john@example.com",
5 status: "pending"
6};
7 
8const fileObject: FileObject = {
9 fileName: "application.json",
10 fileContent: formData,
11 path: "/forms/application.json"
12};
13 
14let result = await aquafier.createGenesisRevision(fileObject, true); // isForm=true
15let aquaTree = result.data.aquaTree;
16 
17// 2. Sign
18result = await aquafier.signRevision(aquaTree, "did", credentials);
19aquaTree = result.data.aquaTree;
20 
21// 3. Witness
22result = await aquafier.witnessRevision(aquaTree, "nostr", witnessConfig, credentials);
23aquaTree = result.data.aquaTree;
24 
25// 4. Verify form
26const verifyResult = await aquafier.verifyFormRevision(aquaTree, formData);
27console.log("Form valid:", verifyResult.isOk);

Error Handling

All methods return Result<T, E> type. Always check for errors:

Code
typescript
1const result = await aquafier.createGenesisRevision(fileObject);
2 
3if (result.isErr) {
4 // Handle error
5 console.error("Failed to create genesis:");
6 result.data.forEach(log => {
7 console.error(`[${log.logType}] ${log.log}`);
8 });
9 return;
10}
11 
12// Success
13const aquaTree = result.data.aquaTree;

Best Practices

  1. Always verify results: Check isErr before using data
  2. Store credentials securely: Never commit mnemonic/keys
  3. Use environment variables: Store sensitive data in .env
  4. Validate inputs: Check file sizes and formats before processing
  5. Handle logs: Display or log all LogData for debugging
  6. Test on testnets: Use Sepolia/Holesky before mainnet
  7. Save AquaTrees: Persist JSON after each operation
  8. Verify chains: Run verification after receiving AquaTrees

Testing

Create credentials.json for testing:

Code
json
1{
2 "mnemonic": "your test mnemonic",
3 "nostr_sk": "your nostr secret key",
4 "did_key": "your did key",
5 "alchemy_key": "your alchemy api key",
6 "witness_eth_network": "sepolia",
7 "witness_method": "cli"
8}

Run tests:

Code
bash
1npm test

Run specific test file:

Code
bash
1npm test -- ./tests/aquafier.test.ts

See Also

  • Introduction - Getting started
  • Concepts - Core concepts
  • Schema Reference - Revision specifications
  • GitHub Repository - Source code and examples
Edit this pageReport an issue
Previous
Schema Reference

Documentation

  • Getting Started
  • API Reference

Community

  • GitHub

Copyright © 2026 Aqua. All rights reserved.

On this page

InstallationPlatform-Specific ImportsCore APIAquafier ClassCreating RevisionsSigning RevisionsWitnessing RevisionsLinking RevisionsVerificationUtility MethodsType ReferenceCore TypesResult TypeConfiguration TypesPlatform-Specific NotesNode.jsWeb BrowserReact NativeComplete Workflow ExamplesDocument NotarizationMulti-Party ApprovalForm Submission with VerificationError HandlingBest PracticesTestingSee Also