MARS documentation
Rust librariesmars-protocol

mars-protocol · anchor

Public declarations and documentation for mars-protocol::anchor.

Package: mars-protocol · Workspace version: 0.1.0 · Module: anchor

This reference follows declared modules and public syntax, including public implementation methods. Function bodies and constant values are omitted. Feature conditions are retained. Private-module re-exports and trait resolution require the compiler; not every declaration is a root import.

Module condition

#[cfg(feature = "sigil")]

anchor::AnchorRecord

A confirmed on-chain anchor for a MARS entry.

Created after a transaction is committed to the Sigil blockchain, this record links a MARS entry to a specific block and transaction hash, and optionally includes a Merkle proof for independent verification.

#[cfg(feature = "sigil")]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "contracts", derive(schemars::JsonSchema, utoipa::ToSchema))]
#[serde(rename_all = "camelCase")]
pub struct AnchorRecord {
/// DID of the anchored entry.

pub entry_did: String,
/// SHA-256 content hash of the entry's `item_data`.

pub item_data_hash: String,
/// Block height at which the anchor was committed.

pub block_height: u64,
/// Transaction hash on the Sigil chain.

pub tx_hash: String,
/// Timestamp when the anchor was created on-chain.

pub anchor_time: chrono::DateTime<chrono::Utc>,
/// Optional Merkle proof for independent verification.

#[serde(skip_serializing_if = "Option::is_none")]
pub proof: Option<MerkleProof>
}

Source line: 24.

anchor::MerkleProof

A Merkle inclusion proof linking a leaf hash to a root hash.

Verifiers walk the path from the leaf_hash to the root, combining each ProofNode in sequence according to its direction.

MARS Merkle Proof v1 encoding

root, leafHash, and every sibling hash are textual lowercase hexadecimal SHA-256 digests. Each level hashes the UTF-8 bytes of the concatenated left and right hexadecimal strings, then lowercase-hex encodes the resulting digest before processing the next level. This is a compatibility contract; it is intentionally not raw 32-byte digest concatenation.

#[cfg(feature = "sigil")]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "contracts", derive(schemars::JsonSchema, utoipa::ToSchema))]
#[serde(rename_all = "camelCase")]
pub struct MerkleProof {
/// Merkle root hash.

pub root: String,
/// Ordered path of sibling hashes from leaf to root.

pub path: Vec<ProofNode>,
/// Hash of the leaf being proved.

pub leaf_hash: String
}

Source line: 60.

anchor::ProofNode

A single node in a Merkle proof path.

#[cfg(feature = "sigil")]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "contracts", derive(schemars::JsonSchema, utoipa::ToSchema))]
#[serde(rename_all = "camelCase")]
pub struct ProofNode {
/// Sibling hash at this level of the tree.

pub hash: String,
/// Whether this sibling is to the left or right of the current node.

pub direction: Direction
}

Source line: 77.

anchor::Direction

Direction of a sibling node in a Merkle proof path.

#[cfg(feature = "sigil")]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "contracts", derive(schemars::JsonSchema, utoipa::ToSchema))]
#[serde(rename_all = "camelCase")]
pub enum Direction {
    /// Sibling is on the left.
    Left,
    /// Sibling is on the right.
    Right,
}

Source line: 92.

anchor::AnchorStatus

Status of an on-chain anchor operation.

#[cfg(feature = "sigil")]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "contracts", derive(schemars::JsonSchema, utoipa::ToSchema))]
#[serde(rename_all = "camelCase", tag = "status")]
pub enum AnchorStatus {
    /// Transaction submitted but not yet confirmed.
    Pending,
    /// Transaction confirmed on-chain.
    Confirmed,
    /// Anchor operation failed.
    Failed {
        /// Human-readable failure reason.
        reason: String,
    },
}

Source line: 107.

anchor::AnchorRequest

A request to anchor a MARS entry on the Sigil chain.

#[cfg(feature = "sigil")]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "contracts", derive(schemars::JsonSchema, utoipa::ToSchema))]
#[serde(rename_all = "camelCase")]
pub struct AnchorRequest {
/// DID of the entry to anchor.

pub entry_did: String,
/// SHA-256 content hash of the entry's `item_data`.

pub item_data_hash: String,
/// DID of the publisher submitting the anchor.

pub publisher_did: String,
/// Ed25519 signature over the canonical anchor payload.

pub signature: String
}

Source line: 127.

anchor::AnchorResponse

Response to an anchor submission.

#[cfg(feature = "sigil")]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "contracts", derive(schemars::JsonSchema, utoipa::ToSchema))]
#[serde(rename_all = "camelCase")]
pub struct AnchorResponse {
/// Transaction hash assigned by the Sigil chain.

pub tx_hash: String,
/// Current status of the anchor operation.

pub status: AnchorStatus
}

Source line: 146.

anchor::verify_merkle_proof

Verify a Merkle proof by recomputing the root from the leaf hash.

Walks the proof path from leaf_hash to the root, hashing left/right hexadecimal UTF-8 strings at each level using SHA-256. Returns true if the recomputed lowercase-hex string matches proof.root. See [MerkleProof] for the exact v1 encoding contract.

#[cfg(feature = "sigil")]
pub fn verify_merkle_proof(proof: &MerkleProof) -> bool;

Source line: 163.

anchor::AnchorError

Errors returned by [SigilAnchorClient].

#[cfg(feature = "sigil")]
#[derive(Debug, thiserror::Error)]
pub enum AnchorError {
    /// Network / transport failure.
    #[error("transport error: {0}")]
    Transport(String),
    /// The Sigil node returned a JSON-RPC error.
    #[error("sigil rpc error: {code}: {message}")]
    Rpc {
        /// JSON-RPC error code.
        code: i64,
        /// Human-readable message.
        message: String,
    },
    /// Anchor submission rejected by the chain.
    #[error("anchor rejected: {0}")]
    Rejected(String),
    /// Invalid response payload.
    #[error("invalid response: {0}")]
    InvalidResponse(String),
}

Source line: 202.

anchor::SigilAnchorClient

Async client that mediates real Sigil RPC anchor submission and queries.

Resolvers MUST call [check_revocation] first on every resolution path — the revocation-first invariant from the GAL design doc. The trait does not enforce that ordering; the caller does.

All query methods return Option&lt;serde_json::Value&gt; (or serde_json::Value for the topology snapshot) so this crate can stay free of a sigil-core dependency. Higher layers (sigil-sdk, oas-resolve) deserialize into the canonical typed records.

#[cfg(feature = "sigil")]
#[async_trait::async_trait]
pub trait SigilAnchorClient: Send + Sync {
    /// Submit a MARS entry anchor to the Sigil chain.
    async fn submit_anchor(&self, req: AnchorRequest) -> Result<AnchorResponse, AnchorError>;

    /// Fetch the typed `HmrAnchor` JSON for a DID, or `None` if absent.
    async fn get_hmr(&self, did: &str) -> Result<Option<serde_json::Value>, AnchorError>;

    /// Fetch the typed `MhrAnchor` JSON for a DID, or `None` if absent.
    async fn get_mhr(&self, did: &str) -> Result<Option<serde_json::Value>, AnchorError>;

    /// Fetch the typed `EnrAnchor` JSON for a DID, or `None` if absent.
    async fn get_enr(&self, did: &str) -> Result<Option<serde_json::Value>, AnchorError>;

    /// Fetch the typed `OrgLineageRoot` JSON for an org DID, or `None` if
    /// absent.
    async fn get_org_root(&self, org_did: &str) -> Result<Option<serde_json::Value>, AnchorError>;

    /// Fetch the `ShardAssignment` (and any topology lineage) for a subject
    /// DID, or `None` if absent.
    async fn get_shard_assignment(
        &self,
        did: &str,
    ) -> Result<Option<serde_json::Value>, AnchorError>;

    /// **Revocation-first**: fetch the `RevocationStatus` JSON for a DID.
    /// Always succeeds; an unrevoked DID returns
    /// `{ "revoked": false, "record": null }`.
    async fn check_revocation(&self, did: &str) -> Result<serde_json::Value, AnchorError>;

    /// Fetch the full `ShardTopologyEntry` snapshot.
    async fn get_shard_topology(&self) -> Result<serde_json::Value, AnchorError>;
}

Source line: 233.

anchor::MockSigilAnchorClient

Deterministic in-memory SigilAnchorClient impl for development and integration tests.

Building a release with --features prod and --features mock-anchor triggers a top-of-crate compile_error!, so the mock cannot ship to production by accident.

#[cfg(feature = "sigil")]
#[cfg(feature = "mock-anchor")]
pub struct MockSigilAnchorClient {

}

Source line: 277.

anchor::MockSigilAnchorClient::new

Create an empty mock client.

#[cfg(feature = "sigil")]
#[cfg(feature = "mock-anchor")]
pub fn new() -> Self;

Source line: 305.

anchor::MockSigilAnchorClient::insert_hmr

Pre-populate an HMR record at the given DID.

#[cfg(feature = "sigil")]
#[cfg(feature = "mock-anchor")]
pub fn insert_hmr(&self, did: &str, record: serde_json::Value) -> Result<(), AnchorError>;

Source line: 316.

anchor::MockSigilAnchorClient::insert_mhr

Pre-populate an MHR record.

#[cfg(feature = "sigil")]
#[cfg(feature = "mock-anchor")]
pub fn insert_mhr(&self, did: &str, record: serde_json::Value) -> Result<(), AnchorError>;

Source line: 322.

anchor::MockSigilAnchorClient::insert_enr

Pre-populate an ENR record.

#[cfg(feature = "sigil")]
#[cfg(feature = "mock-anchor")]
pub fn insert_enr(&self, did: &str, record: serde_json::Value) -> Result<(), AnchorError>;

Source line: 328.

anchor::MockSigilAnchorClient::insert_org_root

Pre-populate an org lineage root.

#[cfg(feature = "sigil")]
#[cfg(feature = "mock-anchor")]
pub fn insert_org_root(
        &self,
        org_did: &str,
        record: serde_json::Value,
    ) -> Result<(), AnchorError>;

Source line: 334.

anchor::MockSigilAnchorClient::insert_shard_assignment

Pre-populate a shard assignment.

#[cfg(feature = "sigil")]
#[cfg(feature = "mock-anchor")]
pub fn insert_shard_assignment(
        &self,
        did: &str,
        record: serde_json::Value,
    ) -> Result<(), AnchorError>;

Source line: 346.

anchor::MockSigilAnchorClient::insert_revocation

Mark a DID as revoked.

#[cfg(feature = "sigil")]
#[cfg(feature = "mock-anchor")]
pub fn insert_revocation(
        &self,
        did: &str,
        record: serde_json::Value,
    ) -> Result<(), AnchorError>;

Source line: 356.

anchor::MockSigilAnchorClient::set_topology

Set the full topology snapshot.

#[cfg(feature = "sigil")]
#[cfg(feature = "mock-anchor")]
pub fn set_topology(&self, snapshot: serde_json::Value) -> Result<(), AnchorError>;

Source line: 369.

anchor::MockSigilAnchorClient::anchor_for

Look up an anchor record by entry DID (for tests).

#[cfg(feature = "sigil")]
#[cfg(feature = "mock-anchor")]
pub fn anchor_for(&self, entry_did: &str) -> Result<Option<AnchorRecord>, AnchorError>;

Source line: 375.

Source provenance

Source: mars-protocol/src/anchor.rs · SHA-256 01fe89586dcca37ad30197952dad161545b2d648d1e90aa403645af3fefe9f7a. Package overview.

On this page