Kanari Network: A Decentralized Metadata Management Protocol

Technical Whitepaper

https://kanari.network

Version 1.0.0 (February 2025)

Abstract

Kanari Network is a decentralized protocol for managing metadata about digital assets with cryptographic guarantees for integrity, provenance, access control, and versioning. Existing decentralized storage solutions address content availability but do not provide a unified, auditable system for metadata lifecycle management. Kanari combines the Move VM's safety model with on-chain records to create tamper-evident metadata entries, verifiable ownership, and fine-grained permissioning without relying on centralized intermediaries.

The protocol captures metadata as immutable, signed records linked into an append-only history. Access controls and delegation are expressed as verifiable capabilities, while efficient indexing and compact proofs enable external verifiers to confirm state without trusting any single operator. Kanari targets applications that require enterprise-grade metadata guarantees: provenance tracking, digital rights management, institutional registries, and composable Web3 services.

1. Introduction

Digital assets increasingly depend on metadata: descriptive attributes, provenance, licensing, and version history. When metadata is centralized, it becomes a single point of failure and a vector for tampering. Decentralized storage systems (e.g., IPFS) solve content addressing and distribution, but they leave the metadata layer under-specified: ownership claims, structured permissions, and authoritative updates remain brittle or off-chain.

Key limitations of current approaches:

  • Lack of authoritative metadata records that are both tamper-evident and efficiently verifiable.
  • Weak or absent mechanisms for delegating and enforcing access and update rights.
  • Fragmented provenance models that hinder composability and auditability.
  • Poorly defined version semantics across storage and registry layers.

Kanari addresses these gaps by providing:

  • Cryptographically anchored metadata records managed by Move-based smart contracts.
  • Clear ownership semantics with transfer, delegation, and revocation primitives.
  • Versioning and immutable change history for each metadata object.
  • Compact proofs and APIs for off-chain verifiers and indexing services.

In the sections that follow, we describe Kanari's data model, Move contracts and native extensions used to enforce policy, the protocol's primitives for ownership and delegation, and how clients and indexers interact to achieve scalable, auditable metadata management.

2. Data Model and Primitives

This chapter defines the canonical data structures and low-level primitives Kanari exposes to clients and on-chain Move modules. The model is intentionally minimal to enable composability while providing strong cryptographic guarantees.

2.1 Metadata Object

  • Identifier: a globally unique ObjectId computed as a hash of an origin address, a local sequence number, and a namespace tag.
  • Owner: an on-chain account address that holds the canonical ownership capability for the object.
  • Payload: an opaque, application-defined JSON or binary blob containing descriptive attributes, URIs, and schema pointers.
  • Head: a reference to the latest metadata record (by record hash) in the object's append-only history.

2.2 Metadata Record

  • RecordHash: the cryptographic hash of the record contents.
  • Prev: the previous RecordHash (or null for genesis), forming an append-only chain.
  • Author: the signer address that produced the update.
  • Timestamp: logical block time when the update was committed.
  • PayloadDiff: either a full payload or a minimal delta describing the change.
  • Signatures: optional external signatures for off-chain attestations.

2.3 Capabilities and Permissions

Kanari models access control using capability objects that are transferrable and revocable:

  • OwnerCapability: grants full rights to publish updates and transfer ownership.
  • UpdateCapability: grants rights to submit updates but not to transfer ownership.
  • IndexerCapability: read-only capability for trusted indexers to annotate metadata with derived indices.

Capabilities are first-class Move resources; transferring and revoking capabilities is a protocol primitive enforced by Move modules.

2.4 Primitives

  • publish_metadata(object_id, payload_diff, capability): appends a new record to the object's history when the caller holds a valid capability.
  • transfer_ownership(object_id, new_owner, owner_capability): atomically transfers OwnerCapability.
  • revoke_capability(object_id, cap_id, owner_capability): invalidates a delegated capability.
  • get_record(record_hash): returns the full record for verification and proof construction.

2.5 Compact Proofs and External Verification

To enable lightweight verification by off-chain clients, Kanari supports compact Merkle-like proofs that prove inclusion of a RecordHash in an object's history head. Proofs are produced by on-chain routines and can be validated with the object's head and the protocol's canonical hashing scheme.

2.6 Storage and Off-chain Indexing

Metadata payloads can be stored off-chain (e.g., IPFS, S3) with on-chain records anchoring URIs and content hashes. Indexers maintain materialized views and provide APIs for search, but canonical authority remains the on-chain record chain.

Summary

Kanari's data model balances expressiveness and verifiability: small, strongly-typed on-chain records anchor flexible off-chain payloads, while capability-based access control enables secure delegation patterns required by enterprise workflows.

Code mapping (where to find these concepts in the repository)

  • crates/kanari-types/src/object.rs: canonical ObjectId and object-related types used by Rust code and the runtime.
  • crates/kanari-types/src/tx_context.rs and src/kanari.rs: transaction and ownership-related types referenced by client code.
  • crates/kanari-frameworks/packages/kanari-system/sources/object.move: Move-side object model and head-management primitives.
  • crates/kanari-frameworks/packages/kanari-system/sources/tx_context.move: Move-side transaction/context primitives and capability semantics.
  • crates/kanari-move-runtime/src/storage/object_storage.rs and src/move_runtime/object_ops.rs: runtime storage handling and object history organization.
  • crates/smt/src/sparse_merkle.rs: sparse Merkle / compact proof utilities used by the runtime for inclusion proofs.
  • crates/kanari-frameworks/packages/kanari-system/sources/event.move and crates/kanari-system/tests/event_tests.move: event formats and examples consumed by indexers.

These files contain the authoritative implementation of the types and primitives described above; use them as primary references when implementing clients, indexers, or Move modules that interoperate with Kanari.

3. System Architecture and Components

This chapter outlines Kanari's runtime architecture, the role of Move contracts and native extensions, and the interactions between clients, indexers, and storage providers.

3.1 Principled Layers

  • Consensus & Execution: The underlying blockchain provides finality and ordering for metadata updates. Move contracts encode protocol state and enforce capability checks.
  • On-chain Registry: Lightweight Move modules store object heads, capability tables, and pointers to payload storage.
  • Native Extensions: Performance-sensitive operations (compact proof generation, advanced hashing) can be implemented as native functions exposed to Move while preserving deterministic behavior.
  • Indexing Layer: Off-chain indexers subscribe to events and maintain searchable views, offering APIs for queries and bulk export.
  • Storage Layer: Large payloads live off-chain with integrity anchored on-chain via content hashes and URIs.

3.2 Move Modules

Key Move modules include:

  • kanari_registry: core types and primitives for object creation, head updates, and capability management.
  • kanari_access: higher-level policies for delegation, roles, and revocation semantics.
  • kanari_proofs: utilities for constructing and verifying compact inclusion proofs.

3.3 Eventing and Observability

Updates emit structured events containing ObjectId, new RecordHash, author, and minimal metadata useful to indexers. Events are the canonical change-stream for off-chain consumers.

3.4 Client Workflows

  • Create: client generates an ObjectId, stores payload off-chain, calls create_object with payload hash and initial capability assignment.
  • Update: authorized client calls publish_metadata with a PayloadDiff; Move module validates capability and appends a new record.
  • Transfer: owner calls transfer_ownership, which atomically hands off capabilities and emits transfer events.
  • Verify: any verifier fetches the object's head, retrieves the record chain (or a proof), and validates record hashes and signatures.

3.5 Indexers and Search

Indexers consume events and materialize views optimized for query types: by owner, by schema type, or by temporal range. Indexers may optionally hold IndexerCapability to annotate records with derived metadata (e.g., text extraction), but annotations do not change canonical on-chain records.

3.6 Security Considerations

  • Minimize on-chain payloads: keep authoritative data small and verifiable; store bulk data off-chain.
  • Capability hygiene: prefer short-lived or narrow-scope capabilities to reduce blast radius.
  • Deterministic natives: ensure any native functions used for proof generation are deterministic across validator nodes.
  • Auditing: comprehensive event logs and compact proofs enable external auditors to reconstruct histories without trusting indexers.

3.7 Scalability and Performance

Kanari offloads heavy payload storage and full-text indexing to off-chain systems while keeping a compact, cryptographically secure on-chain state. This hybrid approach scales to millions of objects while ensuring a single canonical source of truth for ownership and versioning.

Summary

Kanari's architecture combines Move's strong safety semantics with targeted native extensions and off-chain services to deliver a practical, auditable metadata management system suitable for both open ecosystems and enterprise deployments.

Code mapping (where to find implementation in the repo)

  • Move sources and on-chain modules: crates/kanari-frameworks/packages/kanari-system/sources/ (files of interest: kanari.move, object.move, tx_context.move, event.move, transfer.move, coin.move, balance.move). These Move files implement the on-chain record heads, capability resources and events.
  • Runtime & native helpers: crates/kanari-move-runtime/src/move_runtime/ (e.g., helpers.rs, object_ops.rs, move_runtime_extensions.rs) and storage under crates/kanari-move-runtime/src/storage/ — runtime enforcement, proof helpers, and native functions live here.
  • Sparse Merkle and hashing primitives used for compact proofs: crates/smt/src/ (notably sparse_merkle.rs and hash.rs).
  • Canonical Rust types for objects, coins, balances and transactions: crates/kanari-types/src/ (files: object.rs, coin.rs, balance.rs, tx_context.rs, kanari.rs).
  • RPC surface used by indexers / clients: crates/kanari-rpc-server/src/ (modules for block, transaction, module, balance expose server endpoints and event streaming patterns).
  • Cryptography & signatures used by clients and attestations: crates/kanari-crypto/src/ (keys, keystore, signatures, and wallet utilities).
  • Tests and examples demonstrating end-to-end flows: crates/kanari-move-runtime/examples/ (e2e token/nft examples) and Move tests under crates/kanari-frameworks/packages/kanari-system/tests/.

Use these files as the ground truth when updating or extending the system; the chapter text maps directly to the modules and crates above.

4. Move Modules and On-Chain Schemas

This chapter maps the high-level data model and primitives to the actual Move modules in the repository and explains the on-chain schema shapes used by Kanari's Move packages.

4.1 Key Move modules (repo locations)

  • crates/kanari-frameworks/packages/kanari-system/sources/kanari.move — protocol-level types and common constants used across modules.
  • crates/kanari-frameworks/packages/kanari-system/sources/object.move — object creation, head storage, and history anchoring primitives.
  • crates/kanari-frameworks/packages/kanari-system/sources/tx_context.move — transaction-context types and helpers for capability checks.
  • crates/kanari-frameworks/packages/kanari-system/sources/event.move — event shapes emitted by protocol actions (used by indexers).
  • crates/kanari-frameworks/packages/kanari-system/sources/transfer.move and coin.move — examples of asset transfer semantics and token interactions that coexist with metadata operations.

4.2 On-chain resources and types

Common Move resource shapes used by Kanari:

  • ObjectHead (or similar): stores the current RecordHash for an object and possibly a sequence counter.
  • MetadataRecord (stored off-chain or emitted as events): small on-chain footprint referencing an off-chain payload_hash and prev_record_hash.
  • Capability resources: typed resources representing OwnerCapability, UpdateCapability, and IndexerCapability attached to accounts or object tables.

4.3 Storage tables and indexing in Move

Move modules keep small tables keyed by ObjectId or account address. Look for Table or vector-backed storages inside the Move sources; these ensure efficient lookup of heads and capability assignments.

4.4 Events emitted by Move

Move modules publish events for authoritative changes. Event fields commonly include object_id, record_hash, author, and timestamp. Indexers rely on these events to build materialized views.

4.5 How Move and the Rust runtime interoperate

  • Move modules define the protocol invariants and resource types; the Rust runtime (crates/kanari-move-runtime) executes Move bytecode, enforces caps, and implements low-level storage and proof helpers.
  • Native functions exposed to Move (in move_runtime_extensions.rs) provide performance-sensitive primitives, such as hashing or proof construction, that remain deterministic across validators.

References

  • Move sources: crates/kanari-frameworks/packages/kanari-system/sources/
  • Runtime: crates/kanari-move-runtime/src/move_runtime/ and crates/kanari-move-runtime/src/storage/

5. Runtime, Storage, and Proofs Implementation

This chapter explains how Kanari's Rust runtime implements storage, object history, and compact proofs used for efficient verification by off-chain clients.

5.1 Runtime components (repo locations)

  • crates/kanari-move-runtime/src/lib.rs — top-level runtime integration.
  • crates/kanari-move-runtime/src/move_runtime/mod.rs and helpers.rs — runtime helpers and native extension registration.
  • crates/kanari-move-runtime/src/move_runtime/object_ops.rs — object-level operations (head updates, fetches).
  • crates/kanari-move-runtime/src/storage/object_storage.rs — persistent storage layer for object state.
  • crates/smt/src/sparse_merkle.rs and hash.rs — sparse Merkle tree implementation and hashing primitives used to build compact inclusion proofs.

5.2 Object history and compact proofs

  • Each object's head is anchored on-chain (small RecordHash). The full record chain may be stored off-chain or reconstructed by indexers. To verify inclusion without fetching the full chain, the runtime can construct a sparse-merkle-like proof proving that a RecordHash equals the head at a particular sequence.
  • Proof verification uses crates/smt helpers; ensure clients use the same canonical hashing scheme found in crates/smt/src/hash.rs.

5.3 Native functions and determinism

  • Natives implemented under move_runtime_extensions.rs must be deterministic across validator nodes. They should avoid filesystem or RNG usage that would diverge execution.

5.4 Persistence and shared DB

  • Persistent disk-backed stores are implemented under crates/kanari-move-runtime/src/storage/persistent_store.rs (and related shared DB files). These modules manage serialization formats and recovery semantics.

5.5 Tests & examples

  • See crates/kanari-move-runtime/examples/ for e2e examples (e2e_nft_publish.rs, e2e_token_publish.rs) demonstrating publishing and verifying metadata flows.

6. Client APIs, RPCs, and Indexers

This chapter documents the client-facing APIs, RPC surface, and the role of indexers in the Kanari ecosystem, including where to find server and RPC code in the repository.

6.1 RPC server and endpoints

  • crates/kanari-rpc-server/src/ implements the RPC server used by indexers and clients. Notable submodules:
    • block/mod.rs — block and chain queries
    • transaction/mod.rs — transaction submission and status
    • module/mod.rs — module queries and metadata
    • balance/mod.rs — coin/balance related endpoints

6.2 Client flows

  • Create object: client computes ObjectId, stores payload off-chain, calls Move transaction via RPC that invokes create_object Move entrypoint.
  • Update object: client signs and submits a transaction that calls publish_metadata with a payload_hash or payload_diff. RPC returns committed tx_hash and emitted Event (including record_hash).
  • Verify object: client fetches object's head via RPC (get_object_head or similar), requests a compact proof from an indexer or runtime, and validates the proof using crates/smt hashing utilities.

6.3 Indexers and event consumption

  • Indexers subscribe to on-chain events (emitted by Move modules) and materialize views optimized for queries. The repository does not include a single indexer service; however the RPC server and event.move describe the event shapes indexers must consume.
  • Best practice: indexers optionally hold IndexerCapability to perform derived annotations, but should never alter canonical on-chain records.

6.4 Example clients & utilities

  • Client-side cryptography and keystore helpers are in crates/kanari-crypto/src/ (keys, signatures, wallet). Re-use these utilities to ensure compatible signature formats and address derivations.
  • Integration examples may be found under packages/kanari_flutter and crates/kanari-move-runtime/examples/.

7. Security, Deployment, and Operational Considerations

This chapter covers security best practices, deployment notes, and operational guidance tied to the repository's implementation.

7.1 Cryptography & key management

  • Use crates/kanari-crypto for canonical keypair formats, signing, and keystore storage. Ensure client wallets use the same address derivation and signature prefixes expected by the runtime and RPC.
  • Rotate keys and support hardware-backed keystores for high-value owners and indexers.

7.2 Capability hygiene and least privilege

  • Prefer issuing narrow-scoped UpdateCapability objects instead of full OwnerCapability when delegating.
  • Implement short expiration semantics for delegated capabilities where applicable; revocation is provided by Move modules.

7.3 Deterministic natives & validator safety

  • Any native function added under crates/kanari-move-runtime/src/move_runtime/ must be deterministic and thoroughly tested under the test harness in crates/kanari-move-runtime/tests/.

7.4 Backups, snapshots, and proof export

  • Persistent stores under crates/kanari-move-runtime/src/storage/ should be regularly snapshotted. Export compact proofs and event logs for external auditing.

7.5 Testing and CI

  • Unit tests: run cargo test -p <crate> for targeted crates.
  • Integration/e2e: use examples under crates/kanari-move-runtime/examples/ and Move tests under crates/kanari-frameworks/packages/kanari-system/tests/.

7.6 Deployment checklist

  • Verify native extension determinism across validator builds
  • Ensure indexers are configured to consume and persist events reliably
  • Configure monitoring for event lag, proof-generation latency, and storage health

References

  • Crypto utilities: crates/kanari-crypto/src/
  • Runtime storage: crates/kanari-move-runtime/src/storage/
  • Tests & examples: crates/kanari-move-runtime/examples/, crates/kanari-frameworks/packages/kanari-system/tests/