Skip to content

feat: implement vc-schema-registry contract #3#11

Merged
aguilar1x merged 1 commit into
ACTA-Team:mainfrom
Michellebuchiokonicha:feat/vc-schema-registry-contract
Jul 8, 2026
Merged

feat: implement vc-schema-registry contract #3#11
aguilar1x merged 1 commit into
ACTA-Team:mainfrom
Michellebuchiokonicha:feat/vc-schema-registry-contract

Conversation

@Michellebuchiokonicha

@Michellebuchiokonicha Michellebuchiokonicha commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Scaffolds the vc-schema-registry Soroban contract (initialize, register_schema, deprecate_schema, update_schema_uri, get_schema, schema_exists, admin, version), mirroring the vc-issuer-registry storage/error/event conventions. Adds the crate to the workspace.

Closes #3

Summary by CodeRabbit

  • New Features
    • Added a new on-chain VC schema registry contract.
    • Users can now initialize an admin, register schemas, deprecate existing schemas, and update schema URIs.
    • Added read-only checks to retrieve schema details, verify existence, and view the current admin.
    • Contract events and error codes are now surfaced for schema lifecycle actions and validation failures.

Scaffolds the vc-schema-registry Soroban contract (initialize,
register_schema, deprecate_schema, update_schema_uri, get_schema,
schema_exists, admin, version), mirroring the vc-issuer-registry
storage/error/event conventions. Adds the crate to the workspace.

Closes ACTA-Team#3
@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

A new vc-schema-registry-contract Soroban crate is added to the workspace. It implements on-chain VC schema registration with admin governance, supporting schema registration, deprecation, and URI updates. The contract uses instance storage for the admin and persistent storage for SchemaRecord entries, emits typed events on state changes, and exposes six typed error codes.

Changes

vc-schema-registry Soroban contract

Layer / File(s) Summary
Workspace and crate scaffolding
Cargo.toml, contracts/vc-schema-registry/Cargo.toml, contracts/vc-schema-registry/src/lib.rs
Registers the new crate in the workspace, defines package metadata and soroban-sdk dependencies, and exposes contract, error, events, and storage modules under #![no_std].
Storage keys, SchemaRecord type, and helpers
contracts/vc-schema-registry/src/storage.rs
Defines TTL constants, DataKey enum (Admin, Schema(Bytes)), SchemaRecord struct (author, uri, deprecated), and all read/write helpers for instance and persistent storage with TTL extension.
Error codes and event definitions
contracts/vc-schema-registry/src/error.rs, contracts/vc-schema-registry/src/events.rs
Adds ContractError enum with six u32-discriminant variants and four #[contractevent] structs (Initialized, SchemaRegistered, SchemaDeprecated, SchemaUriUpdated) with corresponding publish functions.
Contract entry points and auth helpers
contracts/vc-schema-registry/src/contract.rs
Implements VcSchemaRegistryContract with all public entry points (initialize, register_schema, deprecate_schema, update_schema_uri, get_schema, schema_exists, admin, version) plus internal auth and URI validation helpers.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

  • #3 [Implementation] vc-schema-registry contract: This PR directly implements the contract specified in the issue, covering workspace setup, module scaffolding, storage layout, entry points, error codes, and events.
  • #6: The PR adds all contract entry points and the complete module structure that issue #6's tests are intended to cover.
  • #7: The PR adds the full public API of the vc-schema-registry contract that issue #7's documentation work would describe.

Poem

🐇 A schema hops onto the chain,
With URIs tracked and authors named plain.
Deprecation flags wave in the ledger breeze,
Admin and author guard entries with ease.
Events emitted, errors defined neat—
The registry's open, the contract's complete! 🌟

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The scaffold is present, but #3 requires SchemaRecord name/version/content_hash and matching register_schema, which are not implemented. Add the missing schema fields and update register_schema, storage, and queries to match the issue's versioned schema design.
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and matches the main change: implementing the vc-schema-registry contract.
Out of Scope Changes check ✅ Passed All changes stay within the new vc-schema-registry workspace member and its contract scaffold.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Michellebuchiokonicha Michellebuchiokonicha changed the title feat: implement vc-schema-registry contract feat: implement vc-schema-registry contract #3 Jun 24, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
contracts/vc-schema-registry/src/storage.rs (1)

56-66: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Add a persistent-TTL extension helper for schema reads.

write_schema extends the persistent entry's TTL, but there is no equivalent helper for read paths. Pure-read access (get_schema, schema_exists) in contract.rs only extends instance TTL, so a frequently-read but never-rewritten SchemaRecord can expire and be evicted. Consider adding a helper and calling it on reads.

♻️ Proposed helper
 pub fn read_schema(e: &Env, id: &Bytes) -> Option<SchemaRecord> {
     e.storage().persistent().get(&DataKey::Schema(id.clone()))
 }
+
+pub fn extend_schema_ttl(e: &Env, id: &Bytes) {
+    let key = DataKey::Schema(id.clone());
+    if e.storage().persistent().has(&key) {
+        e.storage()
+            .persistent()
+            .extend_ttl(&key, PERSISTENT_TTL_THRESHOLD, PERSISTENT_TTL_EXTEND_TO);
+    }
+}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@contracts/vc-schema-registry/src/storage.rs` around lines 56 - 66, The schema
storage read path currently does not refresh persistent TTL, so frequently
accessed SchemaRecord entries can still expire even when read often. Add a
persistent-TTL extension helper in storage.rs alongside
read_schema/write_schema, using the existing DataKey::Schema and TTL constants,
and invoke it from the pure-read schema paths in contract.rs (such as get_schema
and schema_exists) after successful reads. Keep write_schema behavior unchanged
and reuse the new helper to centralize the persistent TTL refresh logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@contracts/vc-schema-registry/src/contract.rs`:
- Around line 95-105: The read helpers in `get_schema` and `schema_exists` only
refresh the instance TTL, so the persistent `Schema(id)` entry can still expire
on read-heavy paths. Update `contract::get_schema` and `contract::schema_exists`
to invoke the `extend_schema_ttl` helper from `storage.rs` whenever the schema
lookup succeeds, alongside the existing `extend_instance_ttl` call. Keep the
change localized to these read paths and use the existing `storage::read_schema`
/ `storage::has_schema` flow to locate the right spot.

In `@contracts/vc-schema-registry/src/lib.rs`:
- Around line 14-15: The crate declares a test module via `#[cfg(test)] mod
test;` but there is no matching `test.rs` or `test/mod.rs`, so the test build
will fail. Either add the missing backing test module for `test` in this crate,
or remove the `mod test;` declaration from `lib.rs` if it is not needed.

---

Nitpick comments:
In `@contracts/vc-schema-registry/src/storage.rs`:
- Around line 56-66: The schema storage read path currently does not refresh
persistent TTL, so frequently accessed SchemaRecord entries can still expire
even when read often. Add a persistent-TTL extension helper in storage.rs
alongside read_schema/write_schema, using the existing DataKey::Schema and TTL
constants, and invoke it from the pure-read schema paths in contract.rs (such as
get_schema and schema_exists) after successful reads. Keep write_schema behavior
unchanged and reuse the new helper to centralize the persistent TTL refresh
logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0f7bfda0-a599-4e68-866c-581e20b88b09

📥 Commits

Reviewing files that changed from the base of the PR and between 01b522a and 53756cc.

📒 Files selected for processing (7)
  • Cargo.toml
  • contracts/vc-schema-registry/Cargo.toml
  • contracts/vc-schema-registry/src/contract.rs
  • contracts/vc-schema-registry/src/error.rs
  • contracts/vc-schema-registry/src/events.rs
  • contracts/vc-schema-registry/src/lib.rs
  • contracts/vc-schema-registry/src/storage.rs

Comment on lines +95 to +105
pub fn get_schema(e: Env, id: Bytes) -> SchemaRecord {
storage::extend_instance_ttl(&e);
storage::read_schema(&e, &id)
.unwrap_or_else(|| panic_with_error!(&e, ContractError::SchemaNotFound))
}

/// Returns true if a schema with `id` is registered.
pub fn schema_exists(e: Env, id: Bytes) -> bool {
storage::extend_instance_ttl(&e);
storage::has_schema(&e, &id)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Read paths don't refresh the schema entry TTL.

get_schema and schema_exists extend only the instance TTL, not the persistent Schema(id) entry. A read-heavy schema that is never rewritten can have its persistent entry expire. See the suggested extend_schema_ttl helper in storage.rs; call it here after a successful read.

♻️ Proposed change
     pub fn get_schema(e: Env, id: Bytes) -> SchemaRecord {
-        storage::extend_instance_ttl(&e);
-        storage::read_schema(&e, &id)
-            .unwrap_or_else(|| panic_with_error!(&e, ContractError::SchemaNotFound))
+        storage::extend_instance_ttl(&e);
+        storage::extend_schema_ttl(&e, &id);
+        storage::read_schema(&e, &id)
+            .unwrap_or_else(|| panic_with_error!(&e, ContractError::SchemaNotFound))
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@contracts/vc-schema-registry/src/contract.rs` around lines 95 - 105, The read
helpers in `get_schema` and `schema_exists` only refresh the instance TTL, so
the persistent `Schema(id)` entry can still expire on read-heavy paths. Update
`contract::get_schema` and `contract::schema_exists` to invoke the
`extend_schema_ttl` helper from `storage.rs` whenever the schema lookup
succeeds, alongside the existing `extend_instance_ttl` call. Keep the change
localized to these read paths and use the existing `storage::read_schema` /
`storage::has_schema` flow to locate the right spot.

Comment on lines +14 to +15
#[cfg(test)]
mod test;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
fd -t f 'test.rs' contracts/vc-schema-registry/src
fd -t f 'mod.rs' contracts/vc-schema-registry/src/test

Repository: ACTA-Team/contracts-acta-spikes

Length of output: 294


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== repo files ==\n'
git ls-files | rg '^contracts/vc-schema-registry/'

printf '\n== src tree ==\n'
fd -t f . contracts/vc-schema-registry/src

printf '\n== lib.rs ==\n'
cat -n contracts/vc-schema-registry/src/lib.rs

printf '\n== possible test module files ==\n'
fd -t f 'test.rs' contracts/vc-schema-registry
fd -t f 'mod.rs' contracts/vc-schema-registry

Repository: ACTA-Team/contracts-acta-spikes

Length of output: 1196


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== repo files ==\n'
git ls-files | rg '^contracts/vc-schema-registry/'

printf '\n== src tree ==\n'
fd -t f . contracts/vc-schema-registry/src

printf '\n== lib.rs ==\n'
cat -n contracts/vc-schema-registry/src/lib.rs

printf '\n== possible test module files ==\n'
fd -t f 'test.rs' contracts/vc-schema-registry
fd -t f 'mod.rs' contracts/vc-schema-registry

Repository: ACTA-Team/contracts-acta-spikes

Length of output: 1196


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== repo files ==\n'
git ls-files | rg '^contracts/vc-schema-registry/'

printf '\n== src tree ==\n'
fd -t f . contracts/vc-schema-registry/src

printf '\n== lib.rs ==\n'
cat -n contracts/vc-schema-registry/src/lib.rs

printf '\n== possible test module files ==\n'
fd -t f 'test.rs' contracts/vc-schema-registry
fd -t f 'mod.rs' contracts/vc-schema-registry

Repository: ACTA-Team/contracts-acta-spikes

Length of output: 1196


🏁 Script executed:

#!/bin/bash
set -euo pipefail

git ls-files | rg '^contracts/vc-schema-registry/src/(test\.rs|test/mod\.rs)$' || true
git ls-files | rg '^contracts/vc-schema-registry/src/lib\.rs$'

Repository: ACTA-Team/contracts-acta-spikes

Length of output: 209


Add the backing test module or remove this declaration. #[cfg(test)] mod test; has no matching contracts/vc-schema-registry/src/test.rs or contracts/vc-schema-registry/src/test/mod.rs in this crate, so the test build will fail.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@contracts/vc-schema-registry/src/lib.rs` around lines 14 - 15, The crate
declares a test module via `#[cfg(test)] mod test;` but there is no matching
`test.rs` or `test/mod.rs`, so the test build will fail. Either add the missing
backing test module for `test` in this crate, or remove the `mod test;`
declaration from `lib.rs` if it is not needed.

@aguilar1x aguilar1x merged commit 53756cc into ACTA-Team:main Jul 8, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Implementation] vc-schema-registry contract

2 participants