An open API service indexing awesome lists of open source software.

https://github.com/nostrability/schemata-validator-rs

rust jsonschema validator for schemata
https://github.com/nostrability/schemata-validator-rs

json-schema-validator nostr rust

Last synced: about 2 months ago
JSON representation

rust jsonschema validator for schemata

Awesome Lists containing this project

README

          

# schemata-validator-rs

Rust validator for [Nostr](https://nostr.com/) protocol JSON schemas. This is the Rust equivalent of [`@nostrwatch/schemata-js-ajv`](https://github.com/sandwichfarm/nostr-watch), built on top of [`schemata-rs`](https://github.com/nostrability/schemata-rs).

Validates Nostr events, NIP-11 documents, and protocol messages against the canonical [schemata](https://github.com/nostrability/schemata) definitions using Draft 7 JSON Schema.

## Related projects

| Project | Language | Role |
|---------|----------|------|
| [nostrability/schemata](https://github.com/nostrability/schemata) | JSON/JS | Canonical schema definitions |
| [schemata-rs](https://github.com/nostrability/schemata-rs) | Rust | Data crate (schemas + registry) |
| [@nostrwatch/schemata-js-ajv](https://github.com/sandwichfarm/nostr-watch) | JS/TS | JS validator (AJV-based) |

## When to use this

JSON Schema validation is [not suited for runtime hot paths](https://github.com/nostrability/schemata#what-is-it-not-good-for) — it's slow by design due to the breadth of the specification. Use this crate in **CI and integration tests** to catch schema drift at build time, not in production event processing.

Good for:
- CI pipelines that verify your event construction matches the canonical schemas
- Integration tests for clients and relays
- Fuzz testing to discover broken event shapes

Not good for:
- Validating every incoming event at runtime
- Hot paths where latency matters

## Usage

Add as a **dev dependency** in your `Cargo.toml`:

```toml
[dev-dependencies]
schemata-validator-rs = { git = "https://github.com/nostrability/schemata-validator-rs.git" }
schemata-rs = { git = "https://github.com/nostrability/schemata-rs.git" }

# Required until schemata-rs is published on crates.io
[patch."https://github.com/nostrability/schemata-validator-rs.git"]
schemata-rs = { git = "https://github.com/nostrability/schemata-rs.git" }
```

### Example: validate event construction in tests

```rust
use schemata_validator_rs::{validate_note, validate, get_schema};

#[test]
fn my_event_matches_schema() {
let event = serde_json::json!({
"id": "aa".repeat(32),
"pubkey": "bb".repeat(32),
"created_at": 1700000000u64,
"kind": 1,
"tags": [],
"content": "hello world",
"sig": "cc".repeat(64)
});

let result = validate_note(&event);
assert!(result.valid, "errors: {:?}", result.errors);
}

#[test]
fn my_nip11_doc_matches_schema() {
use schemata_validator_rs::validate_nip11;

let result = validate_nip11(&serde_json::json!({
"name": "My Relay",
"supported_nips": [1, 11]
}));
assert!(result.valid);
}

#[test]
fn relay_message_matches_schema() {
use schemata_validator_rs::{validate_message, Subject};

let msg = serde_json::json!(["NOTICE", "rate limited"]);
let result = validate_message(&msg, Subject::Relay, "Notice");
assert!(result.valid);
}

#[test]
fn tag_matches_schema() {
let schema = get_schema("pTagSchema").unwrap();
let tag = serde_json::json!(["p", "aa".repeat(32)]);
let result = validate(schema, &tag);
assert!(result.valid);
}
```

### Example: CI workflow

```yaml
# .github/workflows/schema-validation.yml
name: Schema Validation
on: [push, pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- run: cargo test --test schema_validation
```

For a full working example, see [bugstr](https://github.com/alltheseas/bugstr).

## API

| Function | Description |
|----------|-------------|
| `validate(schema, data)` | Validate data against any JSON schema |
| `validate_note(event)` | Validate a Nostr event (looks up `kind{N}Schema`) |
| `validate_nip11(doc)` | Validate a NIP-11 relay info document |
| `validate_message(msg, subject, slug)` | Validate a relay/client protocol message |
| `get_schema(key)` | Look up a schema from the registry |

### ValidationResult

```rust
struct ValidationResult {
valid: bool, // true if no errors
errors: Vec<…>, // schema violations
warnings: Vec<…>, // additional properties, missing schemas
}
```

Errors are hard schema violations. Warnings flag additional properties not in the schema and unknown kinds/message types.

## License

GPL-3.0-or-later