MVR Provenance Metadata Spec โ
This document describes how provenance metadata is stored and retrieved in the Move Registry (MVR), particularly for validating smart contract deployments with .intoto.jsonl
files.
๐งฑ Metadata Storage Convention โ
๐ Metadata Key Conventions โ
prov_tx
: The transaction digest (hex string) of the original on-chain deployment. Used for verifying that the published bytecode matches.prov_jsonl_0
,prov_jsonl_1
, ...: Chunks of the.intoto.jsonl
file, encoded in base64 and split by byte-length.prov_params_0
,prov_params_1
, ...: Chunks of the base64-encoded JSON that includes extracted function names and parameters.
๐ Chunking Logic โ
Chunks are split based on byte length, not character count, due to on-chain field length constraints. In testing, the maximum reliable chunk size was 16380 bytes per string.
The following function is used to split base64 data:
ts
const splitBase64ByByteLength = (
base64: string,
maxBytes: number,
): string[] => {
const encoder = new TextEncoder();
const bytes = encoder.encode(base64);
const chunks: string[] = [];
for (let i = 0; i < bytes.length; i += maxBytes) {
const slice = bytes.slice(i, i + maxBytes);
chunks.push(new TextDecoder().decode(slice));
}
return chunks;
};
๐พ Storage Targets โ
- App-level metadata is stored via
move_registry::set_metadata
, using the application capability (AppCap
). - Package-level metadata is stored via
package_info::set_metadata
, using thePackageInfo
object.
๐งช Retrieving and Verifying Metadata โ
You can retrieve metadata from MVRโs public API:
https://mainnet.mvr.mystenlabs.com/v1/names/[your_app_name]
The following logic reconstructs the full .intoto.jsonl
and function param JSON:
ts
import { fromBase64 } from "@mysten/sui/utils";
const joinChunks = (prefix: string, metadata: Record<string, string>) => {
const chunks = Object.entries(metadata)
.filter(([key]) => key.startsWith(prefix))
.sort(([a], [b]) => {
const aIndex = parseInt(a.split("_")[1], 10);
const bIndex = parseInt(b.split("_")[1], 10);
return aIndex - bIndex;
})
.map(([, value]) => value);
return chunks.length > 0 ? chunks.join("") : undefined;
};
const getMvrData = async (name: string) => {
const response = await fetch(
`https://mainnet.mvr.mystenlabs.com/v1/names/${name}`,
);
const json = await response.json();
const metadata = json.package_info.metadata || {};
return {
digest: metadata.prov_tx,
provenance: joinChunks("prov_jsonl_", metadata),
params: JSON.parse(
new TextDecoder().decode(
fromBase64(joinChunks("prov_params_", metadata) ?? ""),
),
),
};
};
๐ฏ Usage โ
prov_tx
: Used to retrieve the on-chain package via transaction digest and compare bytecode.prov_jsonl_*
: Used to reconstruct.intoto.jsonl
and verify Sigstore provenance.prov_params_*
: Used by clients to reconstruct function parameter metadata (e.g., for GUI display).
๐ Notes โ
- All metadata is stored using
set_metadata
functions. - Chunks are sorted by index suffix
_0
,_1
, ... - Developers verifying provenance should always compare
.intoto.jsonl
content against the current package hash extracted fromprov_tx
.