Developer Documentation

Technical reference for the vtimestamp on-chain data format, VDXF keys, CLI verification, and MCP server integration.

On-Chain Data Structure

Timestamps are stored on each user's VerusID contentmultimap under the proof.basic VDXF key. Each timestamp is an array of DataDescriptor entries:

contentmultimap: {
  "proof.basic": [
    // Timestamp entry
    { dataDescriptor: { label: ".sha256",      objectdata: "a7f3b2c1d4e5..." } },
    { dataDescriptor: { label: ".title",       objectdata: "Q4 Financial Report" } },
    { dataDescriptor: { label: ".description", objectdata: "Final approved version" } },
    { dataDescriptor: { label: ".filename",    objectdata: "quarterly-report.pdf" } },
    { dataDescriptor: { label: ".filesize",    objectdata: "2097152" } }
  ]
}

The outer key (proof.basic) is a VDXF key — a deterministic i-address derived from the namespace. On testnet this is testidx.vrsctest::proof.basic, on mainnet vtimestamp.vrsc::proof.basic. The labels shown above (.sha256, .title, etc.) are shorthand — on-chain, these are represented as i-addresses listed in the VDXF Key Reference table below.

Each DataDescriptor also includes a mimetype field set to text/plain for all fields, and a version field. These are part of the standard DataDescriptor format.

Fields

  • .sha256 — SHA-256 hash (required, 64 hex chars)
  • .title — Human-readable title (required)
  • .description — Optional description
  • .filename — Original filename (optional)
  • .filesize — File size in bytes as string (optional)

Timestamp Derivation

The timestamp itself is not stored — it's derived from the block that contains the transaction. Use getblock with the block hash from getidentityhistory to get the block time (Unix timestamp) and height.

VDXF Key Reference

All keys are deterministic i-addresses derived from their namespaced names.

KeyTestnet I-AddressMainnet I-AddressPurpose
proof.basic (outer)i6UD4js3jqyjz9Mttmbk2Sh4eCuwLKPLyQiJvkQ3uTKmRoFiE3rtP8YJxryLBKu8enmXContainer for all timestamp data
DataDescriptor (wrapper)i4GC1YGEVD21afWudGoFJVdnfjJ5XWnCQvDataDescriptor wrapper key
.sha256 labeliBCkvv7KC18xd3P164Cvw1pxpLo5FyGEtmiPRekBwQwFxNHf6mE68n8i2iXEnVdk1hw8Document SHA-256 hash
.title labeliHXGu1nW4jQoeooBHPGE58qQGf9wMakEtjiJx4aJf4SRByyNAi4Z93FC7QNaysyU5mdPTimestamp title
.description labeliP1PCTTHPpktP26xTEu1BuwENWMHQaia4DiS8HnXSHWPL7GLkxYS4SpC7QW2Bnyp93T2Optional description
.filename labeli4xgBqX9btMX8tnAjsyVFrgSLnigxPwBw5iBTcwxUDgvqGXGMC26U52522HrsXC8ggoCOriginal filename
.filesize labeliRz2tyZZEwmrxRPSrwN8UTAC8g5KyVkBiEiHBnDKDyKbXeizg322cxLUps7Uodc1udF4File size in bytes

Testnet keys use the testidx.vrsctest:: namespace. Mainnet keys use the vtimestamp.vrsc:: namespace. The DataDescriptor wrapper key is the same on both networks.

Verifying Programmatically

You can verify timestamps using the Verus CLI without the vtimestamp website.

Step 1: Get Identity History

Retrieve all updates for a VerusID:

verus getidentityhistory "alice@" 0 0 0 0

The parameters are: identity, startHeight, endHeight, txCount, txsToSkip. Using 0 for all returns the full history. This returns every updateidentity transaction for that identity, each including height, blockhash, and the full contentmultimap.

Step 2: Find Timestamp Entries

Look for entries where contentmultimap contains the proof.basic key (use the appropriate i-address for your network). Each history entry looks like this:

{
  "height": 4523891,
  "blockhash": "000000000003a1b2c3d4e5f6...",
  "txid": "a1b2c3d4e5f6a7b8c9d0e1f2...",
  "identity": {
    "contentmultimap": {
      "iJvkQ3uTKmRoFiE3rtP8YJxryLBKu8enmX": [
        {
          "i4GC1YGEVD21afWudGoFJVdnfjJ5XWnCQv": {
            "version": 1,
            "label": "iPRekBwQwFxNHf6mE68n8i2iXEnVdk1hw8",
            "mimetype": "text/plain",
            "objectdata": "a7f3b2c1d4e5f6a7b8c9d0e1..."
          }
        },
        ...
      ]
    }
  }
}

Parse the DataDescriptor array to find entries where the label matches the .sha256 i-address for your network. Compare the objectdata value against your computed hash (case-insensitive).

Step 3: Get Block Time

Once you find a matching entry, retrieve the block details:

verus getblock "blockhash_from_history"

The time field in the block response is the Unix timestamp — the consensus-verified moment when that block was mined and your timestamp was recorded.

MCP Server Integration

AI agents can interact with vtimestamp programmatically through Model Context Protocol (MCP) servers. These can be run directly via npx for testing, or configured in your AI tool's MCP settings file (e.g., Claude Desktop's claude_desktop_config.json or Cursor's MCP config).

vtimestamp-mcp (Read-only)

Allows AI agents to verify timestamps and query identity history. No wallet required.

npx vtimestamp-mcp

Provides tools for verifying timestamps, looking up identities, and reading on-chain data. Install from npm.

vtimestamp-mcp-write (Read-write)

Allows AI agents to create timestamps programmatically. Requires a local Verus wallet for signing.

npx vtimestamp-mcp-write

Provides all read tools plus timestamp creation. Install from npm.

Using vtimestamp Data

All vtimestamp data is public on the Verus blockchain. You can read and verify timestamps from your own tools, build alternative verification interfaces, or use the codebase and VDXF key schema as a reference for your own Verus projects.

  • Query any VerusID's timestamps using the VDXF keys above — no API key or permission needed
  • The VDXF key namespace (vtimestamp.vrsc::) is standardized and documented
  • The source code is MIT licensed and available on GitHub