Document Vault Module
The vault module provides a secure, immutable, and auditable system for linking RWA tokens with their legal documents stored on Walrus. It maintains complete version history and supports auditor endorsements.
Overview
The document vault stores metadata about documents (not the documents themselves). Documents are stored encrypted on Walrus, while the vault stores:
- Walrus blob IDs
- Document hashes for integrity verification
- Version history
- Auditor endorsements
- Access key commitments
Key Structures
DocumentRegistry
Central shared registry for all documents:
public struct DocumentRegistry has key {
id: UID,
records: Table<address, DocumentRecord>, // Maps token address to record
total_documents: u64,
}DocumentRecord
Complete record for a single RWA token's documentation:
public struct DocumentRecord has store {
token_address: address,
issuer: address, // Original issuer (only can append versions)
versions: vector<DocumentVersion>, // Immutable version history
auditors: vector<address>, // List of endorsing auditors
created_at: u64,
updated_at: u64,
}DocumentVersion
Individual document version:
public struct DocumentVersion has store {
version_index: u64, // 0-indexed version number
blob_id: String, // Walrus blob ID
blob_object_id: ID, // Walrus object ID
file_hash: vector<u8>, // SHA-256 hash of file
description: String, // Human-readable description
access_key: vector<u8>, // Encrypted access key
metadata: vector<u8>, // JSON metadata
created_at: u64, // Version creation timestamp
created_by: address, // Address that created this version
}Main Functions
register_document()
Register initial document for an RWA token:
public entry fun register_document(
registry: &mut DocumentRegistry,
token_address: address,
blob_id: String,
blob_object_id: ID,
file_hash: vector<u8>,
description: String,
access_key: vector<u8>,
metadata: vector<u8>,
ctx: &mut TxContext
)Parameters:
registry: Mutable reference to DocumentRegistrytoken_address: Address of RWA tokenblob_id: Walrus blob IDblob_object_id: Walrus object IDfile_hash: SHA-256 hash of file (32 bytes)description: Human-readable descriptionaccess_key: Encrypted access keymetadata: JSON metadatactx: Transaction context
Requirements:
- Document must not already exist for this token
- Caller should be token owner
Effects:
- Creates new DocumentRecord
- Adds initial version
- Increments total_documents
- Emits
DocumentRegisteredevent
append_version()
Add new version to existing document (issuer-only):
public entry fun append_version(
registry: &mut DocumentRegistry,
token_address: address,
blob_id: String,
blob_object_id: ID,
file_hash: vector<u8>,
description: String,
access_key: vector<u8>,
metadata: vector<u8>,
ctx: &mut TxContext
)Requirements:
- Document must already exist
- Caller must be the original issuer
- Previous versions are preserved (immutable history)
Effects:
- Appends new version to versions vector
- Updates updated_at timestamp
- Emits
VersionUpdatedevent
endorse_document()
Allow auditors to verify document validity:
public entry fun endorse_document(
registry: &mut DocumentRegistry,
token_address: address,
ctx: &TxContext
)Requirements:
- Document must exist
- Auditor must not have already endorsed
Effects:
- Adds auditor to auditors list
- Emits
DocumentEndorsedevent
get_latest_blob()
Get current Walrus blob ID:
public fun get_latest_blob(
registry: &DocumentRegistry,
token_address: address
): (String, ID)Returns: Tuple of (blob_id, blob_object_id)
get_access_key()
Get encrypted access key (requires token ownership):
public fun get_access_key(
registry: &DocumentRegistry,
token: &RwaToken,
token_address: address
): (vector<u8>, u64)Requirements:
- Caller must own the RWA token
- Document must exist
Returns: Tuple of (access_key, version_index)
Events
DocumentRegistered
public struct DocumentRegistered has copy, drop {
token_address: address,
issuer: address,
blob_id: String,
version_index: u64,
timestamp: u64,
}VersionUpdated
public struct VersionUpdated has copy, drop {
token_address: address,
version_index: u64,
blob_id: String,
timestamp: u64,
}DocumentEndorsed
public struct DocumentEndorsed has copy, drop {
token_address: address,
auditor: address,
timestamp: u64,
}Version History
Document versions are immutable and append-only:
- Version 0: Initial document registration
- Version 1+: Updated versions (amendments, corrections)
- All versions preserved for audit trail
- Cannot delete or modify existing versions
Access Control
Issuer Restrictions
Only the original issuer (token creator) can:
- Append new document versions
- Maintain version history
This ensures:
- Document integrity
- Clear provenance
- Audit trail completeness
Ownership-Based Access
Token owners can:
- Retrieve access keys
- Access encrypted documents
- Verify document integrity
When token transfers:
- New owner gains access
- Previous owner loses access
Walrus Integration
Documents are stored on Walrus decentralized storage:
- Upload: Client encrypts document and uploads to Walrus
- Blob ID: Walrus returns content-addressed blob ID
- Registration: Blob ID stored on-chain in vault
- Download: Token owner retrieves blob ID and downloads from Walrus
- Decryption: Access key used to decrypt document
Usage Examples
Register Document
sui client call \
--package <PACKAGE_ID> \
--module vault \
--function register_document \
--args <REGISTRY_ID> <TOKEN_ADDRESS> "<WALRUS_BLOB_ID>" "<WALRUS_OBJECT_ID>" "[<FILE_HASH_BYTES>]" "Initial Property Deed" '{"encrypted":"key"}' \
--gas-budget 10000000Append Version
sui client call \
--package <PACKAGE_ID> \
--module vault \
--function append_version \
--args <REGISTRY_ID> <TOKEN_ADDRESS> "<NEW_BLOB_ID>" "<NEW_OBJECT_ID>" "[<NEW_HASH>]" "Updated deed with correction" '{"encrypted":"key"}' \
--gas-budget 10000000Endorse Document
sui client call \
--package <PACKAGE_ID> \
--module vault \
--function endorse_document \
--args <REGISTRY_ID> <TOKEN_ADDRESS> \
--gas-budget 10000000Security Considerations
Immutability
- Versions can never be deleted
- History is permanent
- Provides complete audit trail
Integrity Verification
- SHA-256 hashes verify document integrity
- Download and compare hash
- Detects tampering or corruption
Access Key Security
- Access keys are encrypted
- Only token owners can retrieve
- Keys not stored in plaintext on-chain
Auditor System
- Third-party verification
- Immutable endorsements
- Legal compliance support
Best Practices
- Version Descriptions: Use clear, descriptive version descriptions
- Hash Verification: Always verify document hashes after download
- Auditor Verification: Get professional endorsements for legal documents
- Metadata: Store structured metadata in JSON format
- Version Tracking: Document why each version was created
Integration Points
Marketplace
When tokens are traded:
- Access keys transfer to new owner
- Document access follows ownership
- No action needed from seller/buyer
Frontend
Frontend services:
- Upload documents to Walrus
- Register on-chain
- Retrieve and decrypt documents
- Verify integrity
Next Steps
- Learn about ZK Vault for privacy-preserving verification
- Understand Access Control mechanisms
- Review Frontend Documentation