lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README

commit 895ea6f40a73b342460d5f4adc3c100df049e61a
parent ab2a8feecba9740a6e9fe673f3b27e04f07ec952
Author: triesap <tyson@radroots.org>
Date:   Tue,  4 Aug 2026 12:41:54 +0000

fix(release): make crate archives self-contained

- ship package-owned conformance fixture mirrors
- exclude repository-only governance tests
- preserve executable integration coverage in archives
- verify all-feature extracted crate qualification

Diffstat:
Mcrates/blossom/Cargo.toml | 2+-
Mcrates/core/Cargo.toml | 2+-
Acrates/core/tests/fixtures/value_serialization.v1.json | 102+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acrates/core/tests/package_fixture_freshness.rs | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mcrates/core/tests/serde.rs | 3+--
Mcrates/event/Cargo.toml | 2+-
Acrates/event/tests/fixtures/nip01_wire.v1.json | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mcrates/event/tests/parser_robustness.rs | 3+--
Mcrates/event_codec/Cargo.toml | 2+-
Acrates/event_codec/tests/fixtures/knowledge_event_contract_manifest.v2.json | 690+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acrates/event_codec/tests/fixtures/knowledge_event_contract_manifest.v2.sha256 | 1+
Acrates/event_codec/tests/fixtures/knowledge_public_surface.v1.json | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mcrates/event_codec/tests/knowledge_manifest.rs | 8+++-----
Mcrates/geonames/Cargo.toml | 2+-
Acrates/geonames/tests/query.rs | 19+++++++++++++++++++
Mcrates/identity/Cargo.toml | 2+-
Mcrates/identity/tests/conformance.rs | 3+--
Acrates/identity/tests/fixtures/public_values.v1.json | 166+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mcrates/nostr/Cargo.toml | 2+-
Mcrates/nostr_connect/Cargo.toml | 2+-
Acrates/nostr_connect/tests/fixtures/current_session.v1.json | 350+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mcrates/nostr_connect/tests/protocol.rs | 3+--
Mcrates/protocol/Cargo.toml | 2+-
Mcrates/protocol/tests/conformance.rs | 6++----
Acrates/protocol/tests/fixtures/protocol_v1.inventory.json | 890+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acrates/protocol/tests/fixtures/wire_values.v1.json | 153+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mcrates/secrets/Cargo.toml | 2+-
Mcrates/signing/Cargo.toml | 2+-
Mcrates/storage/Cargo.toml | 2+-
Mcrates/storage_sqlite/Cargo.toml | 2+-
Mcrates/sync/Cargo.toml | 2+-
Mcrates/trade/Cargo.toml | 2+-
Mcrates/transport/Cargo.toml | 2+-
Acrates/transport/tests/fixtures/target_uri.v1.json | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mcrates/transport/tests/transport.rs | 3+--
Mcrates/transport_nostr/Cargo.toml | 2+-
36 files changed, 2685 insertions(+), 36 deletions(-)

diff --git a/crates/blossom/Cargo.toml b/crates/blossom/Cargo.toml @@ -13,7 +13,7 @@ documentation = "https://docs.rs/radroots_blossom" readme = "README.md" keywords = ["radroots", "blossom", "nostr", "media"] categories = ["network-programming", "no-std", "web-programming"] -include = ["src/**", "tests/**", "examples/**", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] +include = ["src/**", "tests/**", "!tests/package_boundary.rs", "examples/**", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] [package.metadata.docs.rs] features = ["std", "serde"] diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml @@ -13,7 +13,7 @@ documentation = "https://docs.rs/radroots_core" readme = "README.md" keywords = ["radroots", "local-food", "domain-model"] categories = ["data-structures", "no-std"] -include = ["src/**", "tests/**", "examples/**", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] +include = ["src/**", "tests/**", "!tests/package_boundary.rs", "!tests/package_fixture_freshness.rs", "examples/**", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] [package.metadata.docs.rs] features = ["std", "serde"] diff --git a/crates/core/tests/fixtures/value_serialization.v1.json b/crates/core/tests/fixtures/value_serialization.v1.json @@ -0,0 +1,102 @@ +{ + "suite": "core_value_serialization", + "contract_version": "1.0.0", + "vectors": [ + { + "id": "core_decimal_normalizes_scale_001", + "kind": "core.decimal.serde", + "input": "1.2300", + "expected": "1.23" + }, + { + "id": "core_decimal_normalizes_signed_zero_002", + "kind": "core.decimal.serde", + "input": "-0.000", + "expected": "0" + }, + { + "id": "core_currency_normalizes_case_003", + "kind": "core.currency.serde", + "input": "usd", + "expected": "USD" + }, + { + "id": "core_money_normalizes_values_004", + "kind": "core.money.serde", + "input": { + "amount": "2.500", + "currency": "usd" + }, + "expected": { + "amount": "2.5", + "currency": "USD" + } + }, + { + "id": "core_percent_normalizes_value_005", + "kind": "core.percent.serde", + "input": { + "value": "12.500" + }, + "expected": { + "value": "12.5" + } + }, + { + "id": "core_quantity_normalizes_unit_006", + "kind": "core.quantity.serde", + "input": { + "amount": "1.2500", + "unit": "kilograms", + "label": "crate" + }, + "expected": { + "amount": "1.25", + "unit": "kg", + "label": "crate" + } + }, + { + "id": "core_quantity_omits_absent_label_007", + "kind": "core.quantity.serde", + "input": { + "amount": "3.000", + "unit": "each" + }, + "expected": { + "amount": "3", + "unit": "each" + } + }, + { + "id": "core_unit_normalizes_synonym_008", + "kind": "core.unit.serde", + "input": "pounds", + "expected": "lb" + }, + { + "id": "core_quantity_price_normalizes_nested_values_009", + "kind": "core.quantity_price.serde", + "input": { + "amount": { + "amount": "5.000", + "currency": "eur" + }, + "quantity": { + "amount": "2.000", + "unit": "kilograms" + } + }, + "expected": { + "amount": { + "amount": "5", + "currency": "EUR" + }, + "quantity": { + "amount": "2", + "unit": "kg" + } + } + } + ] +} diff --git a/crates/core/tests/package_fixture_freshness.rs b/crates/core/tests/package_fixture_freshness.rs @@ -0,0 +1,57 @@ +use std::{fs, path::Path}; + +#[test] +fn packaged_conformance_fixtures_match_canonical_contracts() { + let workspace = Path::new(env!("CARGO_MANIFEST_DIR")) + .join("../..") + .canonicalize() + .expect("workspace root"); + for (canonical, packaged) in [ + ( + "contracts/conformance/vectors/core/value_serialization.v1.json", + "crates/core/tests/fixtures/value_serialization.v1.json", + ), + ( + "contracts/conformance/vectors/identity/public_values.v1.json", + "crates/identity/tests/fixtures/public_values.v1.json", + ), + ( + "contracts/conformance/vectors/protocol/wire_values.v1.json", + "crates/protocol/tests/fixtures/wire_values.v1.json", + ), + ( + "contracts/codegen/protocol_v1.inventory.json", + "crates/protocol/tests/fixtures/protocol_v1.inventory.json", + ), + ( + "contracts/conformance/vectors/event/nip01_wire.v1.json", + "crates/event/tests/fixtures/nip01_wire.v1.json", + ), + ( + "contracts/conformance/vectors/nip46/current_session.v1.json", + "crates/nostr_connect/tests/fixtures/current_session.v1.json", + ), + ( + "contracts/conformance/vectors/transport/target_uri.v1.json", + "crates/transport/tests/fixtures/target_uri.v1.json", + ), + ( + "contracts/knowledge/knowledge_event_contract_manifest.v2.json", + "crates/event_codec/tests/fixtures/knowledge_event_contract_manifest.v2.json", + ), + ( + "contracts/knowledge/knowledge_event_contract_manifest.v2.sha256", + "crates/event_codec/tests/fixtures/knowledge_event_contract_manifest.v2.sha256", + ), + ( + "contracts/conformance/vectors/knowledge/public_surface.v1.json", + "crates/event_codec/tests/fixtures/knowledge_public_surface.v1.json", + ), + ] { + assert_eq!( + fs::read(workspace.join(canonical)).expect("canonical fixture"), + fs::read(workspace.join(packaged)).expect("packaged fixture"), + "packaged fixture {packaged} drifted from {canonical}", + ); + } +} diff --git a/crates/core/tests/serde.rs b/crates/core/tests/serde.rs @@ -8,8 +8,7 @@ use std::collections::BTreeSet; use radroots_core::{Currency, Decimal, Money, Percent, Quantity, QuantityPrice, Unit}; use serde_json::Value; -const SERIALIZATION_VECTORS: &str = - include_str!("../../../contracts/conformance/vectors/core/value_serialization.v1.json"); +const SERIALIZATION_VECTORS: &str = include_str!("fixtures/value_serialization.v1.json"); #[test] fn decimal_serializes_as_string() { diff --git a/crates/event/Cargo.toml b/crates/event/Cargo.toml @@ -13,7 +13,7 @@ documentation = "https://docs.rs/radroots_event" readme = "README.md" keywords = ["radroots", "nostr", "events", "local-food"] categories = ["data-structures", "no-std"] -include = ["src/**", "tests/**", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] +include = ["src/**", "tests/**", "!tests/package_boundary.rs", "!tests/source_boundary.rs", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] [package.metadata.docs.rs] features = ["std", "serde", "knowledge"] diff --git a/crates/event/tests/fixtures/nip01_wire.v1.json b/crates/event/tests/fixtures/nip01_wire.v1.json @@ -0,0 +1,81 @@ +{ + "suite": "event", + "contract_version": "1.0.0", + "vectors": [ + { + "id": "nip01_wire_profile_minimal_001", + "kind": "event.nip01_wire.valid", + "input": { + "raw_json": "{\"id\":\"56bfc78223bb2221bad82b539efdec1ade0f56d0eb0e1f592fd387df4b2ceee0\",\"pubkey\":\"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df\",\"created_at\":1700000001,\"kind\":0,\"tags\":[],\"content\":\"{}\",\"sig\":\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\",\"client\":\"radroots-test\"}" + }, + "expected": { + "canonical_id_preimage": "[0,\"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df\",1700000001,0,[],\"{}\"]", + "computed_event_id": "56bfc78223bb2221bad82b539efdec1ade0f56d0eb0e1f592fd387df4b2ceee0", + "extra_fields": [ + "client" + ] + } + }, + { + "id": "nip01_wire_escape_002", + "kind": "event.nip01_wire.valid", + "input": { + "raw_json": "{\"id\":\"bb2ca7d7e3718fb17d70263ff0dc4e8bf4e63b9f425b2e32914a20ca9adc7199\",\"pubkey\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"created_at\":10,\"kind\":1,\"tags\":[[\"t\",\"line\\nsoil\"]],\"content\":\"\\\"\\\\\\n\\r\\t\\b\\f\\u0001\",\"sig\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"}" + }, + "expected": { + "canonical_id_preimage": "[0,\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",10,1,[[\"t\",\"line\\nsoil\"]],\"\\\"\\\\\\n\\r\\t\\b\\f\\u0001\"]", + "computed_event_id": "bb2ca7d7e3718fb17d70263ff0dc4e8bf4e63b9f425b2e32914a20ca9adc7199" + } + }, + { + "id": "nip01_wire_id_mismatch_003", + "kind": "event.nip01_wire.invalid", + "input": { + "raw_json": "{\"id\":\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\",\"pubkey\":\"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df\",\"created_at\":1700000001,\"kind\":0,\"tags\":[],\"content\":\"{}\",\"sig\":\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\"}" + }, + "expected": { + "error": "event_id_mismatch" + } + }, + { + "id": "nip01_wire_root_not_object_004", + "kind": "event.nip01_wire.invalid", + "input": { + "raw_json": "[]" + }, + "expected": { + "error": "root_not_object" + } + }, + { + "id": "nip01_wire_missing_content_005", + "kind": "event.nip01_wire.invalid", + "input": { + "raw_json": "{\"id\":\"56bfc78223bb2221bad82b539efdec1ade0f56d0eb0e1f592fd387df4b2ceee0\",\"pubkey\":\"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df\",\"created_at\":1700000001,\"kind\":0,\"tags\":[],\"sig\":\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\"}" + }, + "expected": { + "error": "missing_content" + } + }, + { + "id": "nip01_wire_empty_tag_006", + "kind": "event.nip01_wire.invalid", + "input": { + "raw_json": "{\"id\":\"56bfc78223bb2221bad82b539efdec1ade0f56d0eb0e1f592fd387df4b2ceee0\",\"pubkey\":\"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df\",\"created_at\":1700000001,\"kind\":0,\"tags\":[[]],\"content\":\"{}\",\"sig\":\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\"}" + }, + "expected": { + "error": "empty_tag" + } + }, + { + "id": "nip01_wire_noncanonical_pubkey_007", + "kind": "event.nip01_wire.invalid", + "input": { + "raw_json": "{\"id\":\"56bfc78223bb2221bad82b539efdec1ade0f56d0eb0e1f592fd387df4b2ceee0\",\"pubkey\":\"585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF\",\"created_at\":1700000001,\"kind\":0,\"tags\":[],\"content\":\"{}\",\"sig\":\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\"}" + }, + "expected": { + "error": "noncanonical_pubkey" + } + } + ] +} diff --git a/crates/event/tests/parser_robustness.rs b/crates/event/tests/parser_robustness.rs @@ -5,8 +5,7 @@ use radroots_event::id::{DTag, EventId, EventSignature, Nip01Coordinate}; use radroots_event::tag::relay_hint::NostrRelayHint; use radroots_event::wire::v1::Nip01EventWire; -const VALID_WIRE_VECTOR: &str = - include_str!("../../../contracts/conformance/vectors/event/nip01_wire.v1.json"); +const VALID_WIRE_VECTOR: &str = include_str!("fixtures/nip01_wire.v1.json"); #[test] fn wire_and_tag_parsers_are_total_over_deterministic_mutation_corpus() { diff --git a/crates/event_codec/Cargo.toml b/crates/event_codec/Cargo.toml @@ -13,7 +13,7 @@ documentation = "https://docs.rs/radroots_event_codec" readme = "README.md" keywords = ["radroots", "nostr", "codec", "events"] categories = ["encoding", "no-std"] -include = ["src/**", "tests/**", "examples/**", "Cargo.toml", "README.md", "COMPATIBILITY.md", "LICENSE-APACHE", "LICENSE-MIT"] +include = ["src/**", "tests/**", "!tests/package_boundary.rs", "examples/**", "Cargo.toml", "README.md", "COMPATIBILITY.md", "LICENSE-APACHE", "LICENSE-MIT"] [package.metadata.docs.rs] features = ["std", "json", "knowledge", "manifests"] diff --git a/crates/event_codec/tests/fixtures/knowledge_event_contract_manifest.v2.json b/crates/event_codec/tests/fixtures/knowledge_event_contract_manifest.v2.json @@ -0,0 +1,690 @@ +{ + "schema_version": 2, + "registry_version": 7, + "radroots_event_version": "0.1.0-alpha", + "radroots_event_codec_version": "0.1.0-alpha", + "contract_count": 11, + "contracts": [ + { + "contract_id": "radroots.knowledge.change_proposal.v1", + "kind": 3464, + "class": "regular", + "standard": "radroots", + "stability": "experimental", + "privacy": "public", + "author_role": "any", + "content_schema": "json_object", + "payload_type": "RadrootsKnowledgeChangeProposal", + "discriminators": [ + { + "type": "tag_equals", + "name": "contract", + "value": "radroots.knowledge.change_proposal.v1" + } + ], + "tag_contracts": [ + { + "name": "contract", + "cardinality": "required_one", + "semantic": "contract", + "value_type": "contract_id", + "relay_indexed": false + }, + { + "name": "evidence", + "cardinality": "optional_many", + "semantic": "evidence", + "value_type": "event_pointer", + "relay_indexed": false + } + ], + "reducers": [ + "knowledge_projection" + ], + "codec_support": { + "encode": true, + "decode": true, + "contract_validation": true, + "verified_decode": true, + "verified_decode_requires_nostr": true + }, + "sdk_builder_support": false, + "sdk_draft_support": false, + "wasm_tag_builder_support": false, + "wasm_verified_decode_support": true, + "deprecated": false, + "replaced_by": null, + "introduced_at": "0.1.0-alpha.2" + }, + { + "contract_id": "radroots.knowledge.claim.v1", + "kind": 3460, + "class": "regular", + "standard": "radroots", + "stability": "experimental", + "privacy": "public", + "author_role": "any", + "content_schema": "json_object", + "payload_type": "RadrootsKnowledgeClaim", + "discriminators": [ + { + "type": "tag_equals", + "name": "contract", + "value": "radroots.knowledge.claim.v1" + } + ], + "tag_contracts": [ + { + "name": "contract", + "cardinality": "required_one", + "semantic": "contract", + "value_type": "contract_id", + "relay_indexed": false + }, + { + "name": "t", + "cardinality": "optional_many", + "semantic": "topic", + "value_type": "text", + "relay_indexed": true + }, + { + "name": "source", + "cardinality": "optional_many", + "semantic": "source", + "value_type": "event_pointer", + "relay_indexed": false + }, + { + "name": "citation", + "cardinality": "optional_many", + "semantic": "citation", + "value_type": "sha256", + "relay_indexed": false + } + ], + "reducers": [ + "knowledge_projection" + ], + "codec_support": { + "encode": true, + "decode": true, + "contract_validation": true, + "verified_decode": true, + "verified_decode_requires_nostr": true + }, + "sdk_builder_support": true, + "sdk_draft_support": true, + "wasm_tag_builder_support": true, + "wasm_verified_decode_support": true, + "deprecated": false, + "replaced_by": null, + "introduced_at": "0.1.0-alpha.2" + }, + { + "contract_id": "radroots.knowledge.contribution_attestation.v1", + "kind": 3465, + "class": "regular", + "standard": "radroots", + "stability": "experimental", + "privacy": "public", + "author_role": "any", + "content_schema": "json_object", + "payload_type": "RadrootsContributionAttestation", + "discriminators": [ + { + "type": "tag_equals", + "name": "contract", + "value": "radroots.knowledge.contribution_attestation.v1" + } + ], + "tag_contracts": [ + { + "name": "contract", + "cardinality": "required_one", + "semantic": "contract", + "value_type": "contract_id", + "relay_indexed": false + }, + { + "name": "evidence", + "cardinality": "optional_many", + "semantic": "evidence", + "value_type": "event_pointer", + "relay_indexed": false + } + ], + "reducers": [ + "knowledge_projection" + ], + "codec_support": { + "encode": true, + "decode": true, + "contract_validation": true, + "verified_decode": true, + "verified_decode_requires_nostr": true + }, + "sdk_builder_support": false, + "sdk_draft_support": false, + "wasm_tag_builder_support": false, + "wasm_verified_decode_support": true, + "deprecated": false, + "replaced_by": null, + "introduced_at": "0.1.0-alpha.2" + }, + { + "contract_id": "radroots.knowledge.evidence_bounty.v1", + "kind": 30451, + "class": "addressable", + "standard": "radroots", + "stability": "experimental", + "privacy": "public", + "author_role": "any", + "content_schema": "json_object", + "payload_type": "RadrootsEvidenceBounty", + "discriminators": [ + { + "type": "tag_equals", + "name": "contract", + "value": "radroots.knowledge.evidence_bounty.v1" + } + ], + "tag_contracts": [ + { + "name": "d", + "cardinality": "required_one", + "semantic": "identifier", + "value_type": "d_tag", + "relay_indexed": true + }, + { + "name": "contract", + "cardinality": "required_one", + "semantic": "contract", + "value_type": "contract_id", + "relay_indexed": false + }, + { + "name": "t", + "cardinality": "optional_many", + "semantic": "topic", + "value_type": "text", + "relay_indexed": true + }, + { + "name": "evidence", + "cardinality": "optional_many", + "semantic": "evidence", + "value_type": "event_pointer", + "relay_indexed": false + } + ], + "reducers": [ + "knowledge_projection" + ], + "codec_support": { + "encode": true, + "decode": true, + "contract_validation": true, + "verified_decode": true, + "verified_decode_requires_nostr": true + }, + "sdk_builder_support": false, + "sdk_draft_support": false, + "wasm_tag_builder_support": false, + "wasm_verified_decode_support": true, + "deprecated": false, + "replaced_by": null, + "introduced_at": "0.1.0-alpha.2" + }, + { + "contract_id": "radroots.knowledge.field_report.v1", + "kind": 3463, + "class": "regular", + "standard": "radroots", + "stability": "experimental", + "privacy": "public", + "author_role": "any", + "content_schema": "json_object", + "payload_type": "RadrootsKnowledgeFieldReport", + "discriminators": [ + { + "type": "tag_equals", + "name": "contract", + "value": "radroots.knowledge.field_report.v1" + } + ], + "tag_contracts": [ + { + "name": "contract", + "cardinality": "required_one", + "semantic": "contract", + "value_type": "contract_id", + "relay_indexed": false + }, + { + "name": "t", + "cardinality": "optional_many", + "semantic": "topic", + "value_type": "text", + "relay_indexed": true + }, + { + "name": "g", + "cardinality": "optional_one", + "semantic": "geohash", + "value_type": "geohash", + "relay_indexed": true + }, + { + "name": "evidence", + "cardinality": "optional_many", + "semantic": "evidence", + "value_type": "event_pointer", + "relay_indexed": false + } + ], + "reducers": [ + "knowledge_projection" + ], + "codec_support": { + "encode": true, + "decode": true, + "contract_validation": true, + "verified_decode": true, + "verified_decode_requires_nostr": true + }, + "sdk_builder_support": true, + "sdk_draft_support": true, + "wasm_tag_builder_support": true, + "wasm_verified_decode_support": true, + "deprecated": false, + "replaced_by": null, + "introduced_at": "0.1.0-alpha.2" + }, + { + "contract_id": "radroots.knowledge.relation.v1", + "kind": 3461, + "class": "regular", + "standard": "radroots", + "stability": "experimental", + "privacy": "public", + "author_role": "any", + "content_schema": "json_object", + "payload_type": "RadrootsKnowledgeRelation", + "discriminators": [ + { + "type": "tag_equals", + "name": "contract", + "value": "radroots.knowledge.relation.v1" + } + ], + "tag_contracts": [ + { + "name": "contract", + "cardinality": "required_one", + "semantic": "contract", + "value_type": "contract_id", + "relay_indexed": false + }, + { + "name": "t", + "cardinality": "optional_many", + "semantic": "topic", + "value_type": "text", + "relay_indexed": true + }, + { + "name": "source", + "cardinality": "optional_many", + "semantic": "source", + "value_type": "event_pointer", + "relay_indexed": false + } + ], + "reducers": [ + "knowledge_projection" + ], + "codec_support": { + "encode": true, + "decode": true, + "contract_validation": true, + "verified_decode": true, + "verified_decode_requires_nostr": true + }, + "sdk_builder_support": true, + "sdk_draft_support": true, + "wasm_tag_builder_support": true, + "wasm_verified_decode_support": true, + "deprecated": false, + "replaced_by": null, + "introduced_at": "0.1.0-alpha.2" + }, + { + "contract_id": "radroots.knowledge.review.v1", + "kind": 3462, + "class": "regular", + "standard": "radroots", + "stability": "experimental", + "privacy": "public", + "author_role": "any", + "content_schema": "json_object", + "payload_type": "RadrootsKnowledgeReview", + "discriminators": [ + { + "type": "tag_equals", + "name": "contract", + "value": "radroots.knowledge.review.v1" + } + ], + "tag_contracts": [ + { + "name": "contract", + "cardinality": "required_one", + "semantic": "contract", + "value_type": "contract_id", + "relay_indexed": false + }, + { + "name": "review_target", + "cardinality": "required_one", + "semantic": "review_target", + "value_type": "event_pointer", + "relay_indexed": false + }, + { + "name": "evidence", + "cardinality": "optional_many", + "semantic": "evidence", + "value_type": "event_pointer", + "relay_indexed": false + } + ], + "reducers": [ + "knowledge_projection" + ], + "codec_support": { + "encode": true, + "decode": true, + "contract_validation": true, + "verified_decode": true, + "verified_decode_requires_nostr": true + }, + "sdk_builder_support": true, + "sdk_draft_support": true, + "wasm_tag_builder_support": true, + "wasm_verified_decode_support": true, + "deprecated": false, + "replaced_by": null, + "introduced_at": "0.1.0-alpha.2" + }, + { + "contract_id": "radroots.knowledge.source.v1", + "kind": 30450, + "class": "addressable", + "standard": "radroots", + "stability": "experimental", + "privacy": "public", + "author_role": "any", + "content_schema": "json_object", + "payload_type": "RadrootsKnowledgeSource", + "discriminators": [ + { + "type": "tag_equals", + "name": "contract", + "value": "radroots.knowledge.source.v1" + } + ], + "tag_contracts": [ + { + "name": "d", + "cardinality": "required_one", + "semantic": "identifier", + "value_type": "d_tag", + "relay_indexed": true + }, + { + "name": "contract", + "cardinality": "required_one", + "semantic": "contract", + "value_type": "contract_id", + "relay_indexed": false + }, + { + "name": "t", + "cardinality": "optional_many", + "semantic": "topic", + "value_type": "text", + "relay_indexed": true + }, + { + "name": "source", + "cardinality": "optional_many", + "semantic": "source", + "value_type": "event_pointer", + "relay_indexed": false + } + ], + "reducers": [ + "knowledge_projection" + ], + "codec_support": { + "encode": true, + "decode": true, + "contract_validation": true, + "verified_decode": true, + "verified_decode_requires_nostr": true + }, + "sdk_builder_support": true, + "sdk_draft_support": true, + "wasm_tag_builder_support": true, + "wasm_verified_decode_support": true, + "deprecated": false, + "replaced_by": null, + "introduced_at": "0.1.0-alpha.2" + }, + { + "contract_id": "radroots.wiki.article.v1", + "kind": 30818, + "class": "addressable", + "standard": "nip54", + "stability": "experimental", + "privacy": "public", + "author_role": "any", + "content_schema": "djot", + "payload_type": "RadrootsWikiArticle", + "discriminators": [ + { + "type": "kind_only" + } + ], + "tag_contracts": [ + { + "name": "d", + "cardinality": "required_one", + "semantic": "identifier", + "value_type": "d_tag", + "relay_indexed": true + }, + { + "name": "title", + "cardinality": "optional_one", + "semantic": "title", + "value_type": "text", + "relay_indexed": false + }, + { + "name": "summary", + "cardinality": "optional_one", + "semantic": "summary", + "value_type": "text", + "relay_indexed": false + }, + { + "name": "published_at", + "cardinality": "optional_one", + "semantic": "published_at", + "value_type": "unix_timestamp", + "relay_indexed": false + }, + { + "name": "t", + "cardinality": "optional_many", + "semantic": "topic", + "value_type": "text", + "relay_indexed": true + }, + { + "name": "source", + "cardinality": "optional_many", + "semantic": "source", + "value_type": "event_pointer", + "relay_indexed": false + }, + { + "name": "a", + "cardinality": "optional_many", + "semantic": "addressable_coordinate", + "value_type": "addressable_coordinate", + "relay_indexed": true + }, + { + "name": "e", + "cardinality": "optional_many", + "semantic": "event_pointer", + "value_type": "event_id", + "relay_indexed": true + } + ], + "reducers": [ + "knowledge_projection" + ], + "codec_support": { + "encode": true, + "decode": true, + "contract_validation": true, + "verified_decode": true, + "verified_decode_requires_nostr": true + }, + "sdk_builder_support": true, + "sdk_draft_support": true, + "wasm_tag_builder_support": true, + "wasm_verified_decode_support": true, + "deprecated": false, + "replaced_by": null, + "introduced_at": "0.1.0-alpha.2" + }, + { + "contract_id": "radroots.wiki.merge_request.v1", + "kind": 818, + "class": "regular", + "standard": "nip54", + "stability": "experimental", + "privacy": "public", + "author_role": "any", + "content_schema": "plain_text", + "payload_type": "RadrootsWikiMergeRequest", + "discriminators": [ + { + "type": "kind_only" + } + ], + "tag_contracts": [ + { + "name": "a", + "cardinality": "required_one", + "semantic": "addressable_coordinate", + "value_type": "addressable_coordinate", + "relay_indexed": true + }, + { + "name": "p", + "cardinality": "required_one", + "semantic": "counterparty", + "value_type": "public_key", + "relay_indexed": true + }, + { + "name": "e", + "cardinality": "required_one", + "semantic": "source", + "value_type": "event_id", + "relay_indexed": true + }, + { + "name": "e", + "cardinality": "optional_one", + "semantic": "previous_event", + "value_type": "event_id", + "relay_indexed": true + } + ], + "reducers": [ + "knowledge_projection" + ], + "codec_support": { + "encode": true, + "decode": true, + "contract_validation": true, + "verified_decode": true, + "verified_decode_requires_nostr": true + }, + "sdk_builder_support": true, + "sdk_draft_support": true, + "wasm_tag_builder_support": true, + "wasm_verified_decode_support": true, + "deprecated": false, + "replaced_by": null, + "introduced_at": "0.1.0-alpha.2" + }, + { + "contract_id": "radroots.wiki.redirect.v1", + "kind": 30819, + "class": "addressable", + "standard": "nip54", + "stability": "experimental", + "privacy": "public", + "author_role": "any", + "content_schema": "empty", + "payload_type": "RadrootsWikiRedirect", + "discriminators": [ + { + "type": "kind_only" + } + ], + "tag_contracts": [ + { + "name": "d", + "cardinality": "required_one", + "semantic": "identifier", + "value_type": "d_tag", + "relay_indexed": true + }, + { + "name": "a", + "cardinality": "required_one", + "semantic": "addressable_coordinate", + "value_type": "addressable_coordinate", + "relay_indexed": true + } + ], + "reducers": [ + "knowledge_projection" + ], + "codec_support": { + "encode": true, + "decode": true, + "contract_validation": true, + "verified_decode": true, + "verified_decode_requires_nostr": true + }, + "sdk_builder_support": true, + "sdk_draft_support": true, + "wasm_tag_builder_support": true, + "wasm_verified_decode_support": true, + "deprecated": false, + "replaced_by": null, + "introduced_at": "0.1.0-alpha.2" + } + ] +} diff --git a/crates/event_codec/tests/fixtures/knowledge_event_contract_manifest.v2.sha256 b/crates/event_codec/tests/fixtures/knowledge_event_contract_manifest.v2.sha256 @@ -0,0 +1 @@ +d75fe077862204dc68c1c2098ddb23ccd4d3829befd6178f52ad21f8a5395a24 diff --git a/crates/event_codec/tests/fixtures/knowledge_public_surface.v1.json b/crates/event_codec/tests/fixtures/knowledge_public_surface.v1.json @@ -0,0 +1,73 @@ +{ + "suite": "knowledge_public_surface", + "contract_version": "1.0.0", + "vectors": [ + { + "id": "knowledge_source_public_surface_valid_001", + "kind": "knowledge.public_surface.valid", + "input": { + "fixture": "knowledge_source_valid" + }, + "expected": { + "contract_id": "radroots.knowledge.source.v1", + "operation": "build_validate_decode_expose" + } + }, + { + "id": "knowledge_claim_public_surface_valid_002", + "kind": "knowledge.public_surface.valid", + "input": { + "fixture": "knowledge_claim_valid" + }, + "expected": { + "contract_id": "radroots.knowledge.claim.v1", + "operation": "build_validate_decode_expose" + } + }, + { + "id": "knowledge_review_public_surface_valid_003", + "kind": "knowledge.public_surface.valid", + "input": { + "fixture": "knowledge_review_valid" + }, + "expected": { + "contract_id": "radroots.knowledge.review.v1", + "operation": "build_validate_decode_expose" + } + }, + { + "id": "knowledge_field_report_public_surface_valid_004", + "kind": "knowledge.public_surface.valid", + "input": { + "fixture": "knowledge_field_report_valid" + }, + "expected": { + "contract_id": "radroots.knowledge.field_report.v1", + "operation": "build_validate_decode_expose" + } + }, + { + "id": "wiki_article_public_surface_valid_005", + "kind": "knowledge.public_surface.valid", + "input": { + "fixture": "wiki_article_valid" + }, + "expected": { + "contract_id": "radroots.wiki.article.v1", + "operation": "build_validate_decode_expose" + } + }, + { + "id": "knowledge_claim_sdk_builder_public_surface_valid_006", + "kind": "knowledge.sdk_builder_event.valid", + "input": { + "sdk": "radroots_sdk", + "builder": "RadrootsKnowledgeClaimBuilder" + }, + "expected": { + "contract_id": "radroots.knowledge.claim.v1", + "operation": "build_event_validate_decode_expose" + } + } + ] +} diff --git a/crates/event_codec/tests/knowledge_manifest.rs b/crates/event_codec/tests/knowledge_manifest.rs @@ -21,12 +21,10 @@ use radroots_event_codec::manifest::{ }; use support::knowledge::RADROOTS_KNOWLEDGE_VALID_CONTRACT_IDS; -const MANIFEST_JSON: &str = - include_str!("../../../contracts/knowledge/knowledge_event_contract_manifest.v2.json"); -const MANIFEST_SHA256: &str = - include_str!("../../../contracts/knowledge/knowledge_event_contract_manifest.v2.sha256"); +const MANIFEST_JSON: &str = include_str!("fixtures/knowledge_event_contract_manifest.v2.json"); +const MANIFEST_SHA256: &str = include_str!("fixtures/knowledge_event_contract_manifest.v2.sha256"); const KNOWLEDGE_PUBLIC_SURFACE_VECTOR: &str = - include_str!("../../../contracts/conformance/vectors/knowledge/public_surface.v1.json"); + include_str!("fixtures/knowledge_public_surface.v1.json"); const MVP_SUPPORT_CONTRACT_IDS: &[&str] = &[ "radroots.wiki.article.v1", diff --git a/crates/geonames/Cargo.toml b/crates/geonames/Cargo.toml @@ -13,7 +13,7 @@ publish = ["crates-io"] documentation = "https://docs.rs/radroots_geonames" keywords = ["radroots", "geonames", "geocoding", "locality"] categories = ["database"] -include = ["src/**", "tests/**", "examples/**", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] +include = ["src/**", "tests/**", "!tests/package_boundary.rs", "examples/**", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] [package.metadata.docs.rs] features = [] diff --git a/crates/geonames/tests/query.rs b/crates/geonames/tests/query.rs @@ -0,0 +1,19 @@ +use radroots_geonames::{Point, Query}; + +#[test] +fn packaged_query_construction_remains_validated_and_inert() { + let locality = Query::locality("Victoria") + .expect("locality") + .with_region("BC") + .expect("region") + .with_country("CA") + .expect("country") + .with_limit(5) + .expect("limit"); + assert_eq!(locality.limit(), 5); + + let reverse = Query::reverse(Point::new(48.4284, -123.3656).expect("point")) + .with_radius_degrees(0.25) + .expect("radius"); + assert_eq!(reverse.limit(), 1); +} diff --git a/crates/identity/Cargo.toml b/crates/identity/Cargo.toml @@ -13,7 +13,7 @@ documentation = "https://docs.rs/radroots_identity" readme = "README.md" keywords = ["radroots", "identity", "nostr", "secp256k1"] categories = ["cryptography", "data-structures", "no-std"] -include = ["src/**", "tests/**", "examples/**", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] +include = ["src/**", "tests/**", "!tests/package_boundary.rs", "!tests/retired_surface.rs", "examples/**", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] [package.metadata.docs.rs] features = ["std", "serde"] diff --git a/crates/identity/tests/conformance.rs b/crates/identity/tests/conformance.rs @@ -8,8 +8,7 @@ use radroots_identity::{ }; use serde_json::Value; -const PUBLIC_VALUE_VECTORS: &str = - include_str!("../../../contracts/conformance/vectors/identity/public_values.v1.json"); +const PUBLIC_VALUE_VECTORS: &str = include_str!("fixtures/public_values.v1.json"); #[test] fn public_value_vectors_are_unique_complete_and_executable() { diff --git a/crates/identity/tests/fixtures/public_values.v1.json b/crates/identity/tests/fixtures/public_values.v1.json @@ -0,0 +1,166 @@ +{ + "suite": "identity_public_values", + "contract_version": "1.0.0", + "vectors": [ + { + "id": "identity_public_key_canonical_hex_001", + "kind": "identity.public_key.serde", + "input": "585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF", + "expected": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df" + }, + { + "id": "identity_identity_id_canonical_hex_002", + "kind": "identity.identity_id.serde", + "input": "E0266E3CFB0D2886F91C73F5F868F3B98273713E5FCD97C081663F5518A4B3AF", + "expected": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af" + }, + { + "id": "identity_account_id_canonical_hex_003", + "kind": "identity.account_id.serde", + "input": "585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF", + "expected": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df" + }, + { + "id": "identity_username_canonical_text_004", + "kind": "identity.username.serde", + "input": " Alice.Farm ", + "expected": "alice.farm" + }, + { + "id": "identity_profile_canonical_username_005", + "kind": "identity.profile.serde", + "input": { + "username": "Alice.Farm" + }, + "expected": { + "username": "alice.farm" + } + }, + { + "id": "identity_public_identity_discards_empty_profile_006", + "kind": "identity.public_identity.serde", + "input": { + "id": "585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF", + "public_key": "585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF", + "profile": {} + }, + "expected": { + "id": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", + "public_key": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df" + } + }, + { + "id": "identity_account_record_canonical_nested_values_007", + "kind": "identity.account_record.serde", + "input": { + "account_id": "585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF", + "public_identity": { + "id": "585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF", + "public_key": "585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF" + }, + "label": "primary", + "created_at_unix": 10, + "updated_at_unix": 12 + }, + "expected": { + "account_id": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", + "public_identity": { + "id": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", + "public_key": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df" + }, + "label": "primary", + "created_at_unix": 10, + "updated_at_unix": 12 + } + }, + { + "id": "identity_account_status_canonical_ready_008", + "kind": "identity.account_status.serde", + "input": { + "ready": { + "account": { + "account_id": "585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF", + "public_identity": { + "id": "585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF", + "public_key": "585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF" + }, + "created_at_unix": 10, + "updated_at_unix": 10 + } + } + }, + "expected": { + "ready": { + "account": { + "account_id": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", + "public_identity": { + "id": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", + "public_key": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df" + }, + "created_at_unix": 10, + "updated_at_unix": 10 + } + } + } + }, + { + "id": "identity_public_key_rejects_invalid_curve_point_009", + "kind": "identity.public_key.invalid", + "input": "0000000000000000000000000000000000000000000000000000000000000000", + "expected_error_contains": "valid secp256k1" + }, + { + "id": "identity_public_identity_rejects_mismatched_id_010", + "kind": "identity.public_identity.invalid", + "input": { + "id": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", + "public_key": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df" + }, + "expected_error_contains": "does not match its public key" + }, + { + "id": "identity_account_record_rejects_mismatched_id_011", + "kind": "identity.account_record.invalid", + "input": { + "account_id": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", + "public_identity": { + "id": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", + "public_key": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df" + }, + "created_at_unix": 10, + "updated_at_unix": 10 + }, + "expected_error_contains": "does not match its public identity" + }, + { + "id": "identity_account_record_rejects_time_reversal_012", + "kind": "identity.account_record.invalid", + "input": { + "account_id": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", + "public_identity": { + "id": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", + "public_key": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df" + }, + "created_at_unix": 10, + "updated_at_unix": 9 + }, + "expected_error_contains": "precedes created timestamp" + }, + { + "id": "identity_username_rejects_dot_placement_013", + "kind": "identity.username.invalid", + "input": ".alice", + "expected_error_contains": "dots cannot be" + }, + { + "id": "identity_public_identity_rejects_unknown_field_014", + "kind": "identity.public_identity.invalid", + "input": { + "id": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", + "public_key": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", + "secret_key": "forbidden" + }, + "expected_error_contains": "unknown field" + } + ] +} diff --git a/crates/nostr/Cargo.toml b/crates/nostr/Cargo.toml @@ -13,7 +13,7 @@ documentation = "https://docs.rs/radroots_nostr" readme = "README.md" keywords = ["radroots", "nostr", "events", "signing"] categories = ["network-programming", "cryptography"] -include = ["src/**", "tests/**", "examples/**", "Cargo.toml", "README.md", "COMPATIBILITY.md", "LICENSE-APACHE", "LICENSE-MIT"] +include = ["src/**", "tests/**", "!tests/generic_builder_boundary.rs", "!tests/package_boundary.rs", "examples/**", "Cargo.toml", "README.md", "COMPATIBILITY.md", "LICENSE-APACHE", "LICENSE-MIT"] [package.metadata.docs.rs] features = ["std", "events", "blossom", "nip17", "signing"] diff --git a/crates/nostr_connect/Cargo.toml b/crates/nostr_connect/Cargo.toml @@ -13,7 +13,7 @@ documentation = "https://docs.rs/radroots_nostr_connect" readme = "README.md" keywords = ["radroots", "nostr", "nip46", "signing"] categories = ["cryptography", "network-programming"] -include = ["src/**", "tests/**", "examples/**", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] +include = ["src/**", "tests/**", "!tests/package_boundary.rs", "examples/**", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] [package.metadata.docs.rs] features = ["serde"] diff --git a/crates/nostr_connect/tests/fixtures/current_session.v1.json b/crates/nostr_connect/tests/fixtures/current_session.v1.json @@ -0,0 +1,350 @@ +{ + "suite": "nip46_current_session", + "contract_version": "1.0.0", + "vectors": [ + { + "id": "nip46_connect_legacy_one_parameter_001", + "kind": "nip46.request.valid", + "input": { + "message": { + "id": "connect-legacy-1", + "method": "connect", + "params": [ + "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df" + ] + } + }, + "expected": { + "normalized_message": { + "id": "connect-legacy-1", + "method": "connect", + "params": [ + "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df" + ] + } + } + }, + { + "id": "nip46_connect_legacy_two_parameters_002", + "kind": "nip46.request.valid", + "input": { + "message": { + "id": "connect-legacy-2", + "method": "connect", + "params": [ + "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", + "fixture-client-secret" + ] + } + }, + "expected": { + "normalized_message": { + "id": "connect-legacy-2", + "method": "connect", + "params": [ + "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", + "fixture-client-secret" + ] + } + } + }, + { + "id": "nip46_connect_legacy_three_parameters_003", + "kind": "nip46.request.valid", + "input": { + "message": { + "id": "connect-legacy-3", + "method": "connect", + "params": [ + "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", + "fixture-client-secret", + "nip44_encrypt,sign_event:1" + ] + } + }, + "expected": { + "normalized_message": { + "id": "connect-legacy-3", + "method": "connect", + "params": [ + "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", + "fixture-client-secret", + "nip44_encrypt,sign_event:1" + ] + } + } + }, + { + "id": "nip46_connect_current_metadata_004", + "kind": "nip46.request.valid", + "input": { + "message": { + "id": "connect-current", + "method": "connect", + "params": [ + "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", + "fixture-client-secret", + "nip44_encrypt,sign_event:1", + "{\"name\":\" Example Client \",\"url\":\"https://app.example.com\",\"image\":\"https://cdn.example.com/logo.png\"}" + ] + } + }, + "expected": { + "normalized_message": { + "id": "connect-current", + "method": "connect", + "params": [ + "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", + "fixture-client-secret", + "nip44_encrypt,sign_event:1", + "{\"name\":\"Example Client\",\"url\":\"https://app.example.com/\",\"image\":\"https://cdn.example.com/logo.png\"}" + ] + } + } + }, + { + "id": "nip46_metadata_name_bound_005", + "kind": "nip46.metadata.invalid", + "input": { + "field": "name", + "repeat": "a", + "count": 129 + }, + "expected": { + "error": "invalid_client_metadata" + } + }, + { + "id": "nip46_connect_malformed_metadata_006", + "kind": "nip46.request.invalid", + "input": { + "message": { + "id": "connect-invalid-metadata", + "method": "connect", + "params": [ + "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", + "", + "", + "{\"name\":\"\"}" + ] + } + }, + "expected": { + "error": "invalid_client_metadata" + } + }, + { + "id": "nip46_nostrconnect_ordered_relays_007", + "kind": "nip46.uri.valid", + "input": { + "uri": "nostrconnect://585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df?relay=wss%3A%2F%2Frelay.example.com&relay=wss%3A%2F%2Frelay-2.example.com&secret=fixture-client-secret&perms=nip44_encrypt%2Csign_event%3A1&name=+Example+Client+&url=https%3A%2F%2Fapp.example.com&image=https%3A%2F%2Fcdn.example.com%2Flogo.png" + }, + "expected": { + "variant": "nostrconnect", + "relays": [ + "wss://relay.example.com", + "wss://relay-2.example.com" + ], + "secret": "fixture-client-secret", + "metadata": { + "name": "Example Client", + "url": "https://app.example.com/", + "image": "https://cdn.example.com/logo.png", + "permissions": "nip44_encrypt,sign_event:1" + } + } + }, + { + "id": "nip46_nostrconnect_secret_required_008", + "kind": "nip46.uri.invalid", + "input": { + "uri": "nostrconnect://585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df?relay=wss%3A%2F%2Frelay.example.com" + }, + "expected": { + "error": "missing_secret" + } + }, + { + "id": "nip46_bunker_secret_optional_009", + "kind": "nip46.uri.valid", + "input": { + "uri": "bunker://585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df?relay=wss%3A%2F%2Frelay.example.com" + }, + "expected": { + "variant": "bunker", + "relays": [ + "wss://relay.example.com" + ], + "secret": null + } + }, + { + "id": "nip46_bunker_secret_present_010", + "kind": "nip46.uri.valid", + "input": { + "uri": "bunker://585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df?relay=wss%3A%2F%2Frelay.example.com&secret=fixture-bunker-secret" + }, + "expected": { + "variant": "bunker", + "relays": [ + "wss://relay.example.com" + ], + "secret": "fixture-bunker-secret" + } + }, + { + "id": "nip46_connect_secret_echo_011", + "kind": "nip46.response.valid", + "input": { + "method": "connect", + "envelope": { + "id": "connect-current", + "result": "fixture-client-secret" + } + }, + "expected": { + "normalized_envelope": { + "id": "connect-current", + "result": "fixture-client-secret" + } + } + }, + { + "id": "nip46_switch_relays_ordered_012", + "kind": "nip46.response.valid", + "input": { + "method": "switch_relays", + "envelope": { + "id": "switch-relays", + "result": [ + "wss://relay-2.example.com", + "wss://relay-3.example.com" + ] + } + }, + "expected": { + "normalized_envelope": { + "id": "switch-relays", + "result": [ + "wss://relay-2.example.com", + "wss://relay-3.example.com" + ] + } + } + }, + { + "id": "nip46_switch_relays_unchanged_013", + "kind": "nip46.response.valid", + "input": { + "method": "switch_relays", + "envelope": { + "id": "switch-relays-unchanged", + "result": null + } + }, + "expected": { + "normalized_envelope": { + "id": "switch-relays-unchanged", + "result": null + } + } + }, + { + "id": "nip46_auth_url_continuation_014", + "kind": "nip46.response.valid", + "input": { + "method": "sign_event", + "envelope": { + "id": "sign-with-auth", + "result": "auth_url", + "error": "https://auth.example.com/challenge" + } + }, + "expected": { + "normalized_envelope": { + "id": "sign-with-auth", + "result": "auth_url", + "error": "https://auth.example.com/challenge" + } + } + }, + { + "id": "nip46_logout_request_015", + "kind": "nip46.request.valid", + "input": { + "message": { + "id": "logout-current", + "method": "logout", + "params": [] + } + }, + "expected": { + "normalized_message": { + "id": "logout-current", + "method": "logout", + "params": [] + } + } + }, + { + "id": "nip46_logout_acknowledgement_016", + "kind": "nip46.response.valid", + "input": { + "method": "logout", + "envelope": { + "id": "logout-current", + "result": "ack" + } + }, + "expected": { + "normalized_envelope": { + "id": "logout-current", + "result": "ack" + } + } + }, + { + "id": "nip46_logout_rejects_parameters_017", + "kind": "nip46.request.invalid", + "input": { + "message": { + "id": "logout-invalid", + "method": "logout", + "params": [ + "unexpected" + ] + } + }, + "expected": { + "error": "invalid_params" + } + }, + { + "id": "nip46_malformed_response_result_018", + "kind": "nip46.response.invalid", + "input": { + "method": "ping", + "envelope": { + "id": "ping-invalid", + "result": 7 + } + }, + "expected": { + "error": "invalid_response_payload" + } + }, + { + "id": "nip46_malformed_response_missing_result_019", + "kind": "nip46.response.invalid", + "input": { + "method": "logout", + "envelope": { + "id": "logout-missing-result" + } + }, + "expected": { + "error": "missing_result" + } + } + ] +} diff --git a/crates/nostr_connect/tests/protocol.rs b/crates/nostr_connect/tests/protocol.rs @@ -453,8 +453,7 @@ fn sign_event_response_roundtrips_signed_event_json_string() { #[test] fn checked_in_current_session_vectors_match_protocol_behavior() { - let vectors = - include_str!("../../../contracts/conformance/vectors/nip46/current_session.v1.json"); + let vectors = include_str!("fixtures/current_session.v1.json"); let document: Value = serde_json::from_str(vectors).expect("NIP-46 vector JSON"); assert_eq!(document["suite"], "nip46_current_session"); assert_eq!(document["contract_version"], "1.0.0"); diff --git a/crates/protocol/Cargo.toml b/crates/protocol/Cargo.toml @@ -13,7 +13,7 @@ documentation = "https://docs.rs/radroots_protocol" readme = "README.md" keywords = ["radroots", "protocol", "local-food", "wire-format"] categories = ["encoding", "no-std"] -include = ["src/**", "tests/**", "examples/**", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] +include = ["src/**", "tests/**", "!tests/package_boundary.rs", "examples/**", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] [package.metadata.docs.rs] features = ["std", "serde"] diff --git a/crates/protocol/tests/conformance.rs b/crates/protocol/tests/conformance.rs @@ -13,10 +13,8 @@ use radroots_protocol::{ use serde::{Serialize, de::DeserializeOwned}; use serde_json::Value; -const WIRE_VECTORS: &str = - include_str!("../../../contracts/conformance/vectors/protocol/wire_values.v1.json"); -const GENERATED_INVENTORY: &str = - include_str!("../../../contracts/codegen/protocol_v1.inventory.json"); +const WIRE_VECTORS: &str = include_str!("fixtures/wire_values.v1.json"); +const GENERATED_INVENTORY: &str = include_str!("fixtures/protocol_v1.inventory.json"); #[test] fn language_neutral_wire_vectors_are_unique_and_executable() { diff --git a/crates/protocol/tests/fixtures/protocol_v1.inventory.json b/crates/protocol/tests/fixtures/protocol_v1.inventory.json @@ -0,0 +1,890 @@ +{ + "schema_version": 1, + "generator": "radroots_xtask.protocol_codegen.v1", + "package": "radroots_protocol", + "source_hash_algorithm": "sha256_bytes_v1", + "sources": [ + { + "module": "capability::v1", + "path": "crates/protocol/src/capability/v1.rs", + "sha256": "db2ac595ff4e45652791df49d3e0129afcac57fb568f71c6b7355e083b359ad6", + "types": [ + { + "rust_path": "radroots_protocol::capability::v1::Availability", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::capability::v1::Maturity", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::capability::v1::MeshScopeId", + "kind": "struct" + }, + { + "rust_path": "radroots_protocol::capability::v1::ReticulumDestination", + "kind": "struct" + }, + { + "rust_path": "radroots_protocol::capability::v1::ReticulumTarget", + "kind": "struct" + }, + { + "rust_path": "radroots_protocol::capability::v1::TransportDescriptor", + "kind": "struct" + }, + { + "rust_path": "radroots_protocol::capability::v1::TransportKind", + "kind": "struct" + } + ] + }, + { + "module": "error::v1", + "path": "crates/protocol/src/error/v1.rs", + "sha256": "3a4043ea8f1a457193c9f0fdcd00427af650b3db560b55dbc64774a8a5013107", + "types": [ + { + "rust_path": "radroots_protocol::error::v1::CapabilityId", + "kind": "struct" + }, + { + "rust_path": "radroots_protocol::error::v1::Class", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::error::v1::Code", + "kind": "struct" + }, + { + "rust_path": "radroots_protocol::error::v1::Detail", + "kind": "struct" + }, + { + "rust_path": "radroots_protocol::error::v1::DetailValue", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::error::v1::ErrorReport", + "kind": "struct" + }, + { + "rust_path": "radroots_protocol::error::v1::RecoveryAction", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::error::v1::SafeDetails", + "kind": "struct" + }, + { + "rust_path": "radroots_protocol::error::v1::SafeMessage", + "kind": "struct" + } + ] + }, + { + "module": "event::v1", + "path": "crates/protocol/src/event/v1.rs", + "sha256": "cc5b36e7e5cef0c7e375c2ce473267f5721994416d5154296a135890dface2e4", + "types": [ + { + "rust_path": "radroots_protocol::event::v1::EventClass", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::event::v1::EventDescriptor", + "kind": "struct" + }, + { + "rust_path": "radroots_protocol::event::v1::TradeState", + "kind": "enum" + } + ] + }, + { + "module": "radrootsd::transport_publish::v5", + "path": "crates/protocol/src/radrootsd/transport_publish/v5.rs", + "sha256": "a562ce9af3fd0e65a31c121c0c73c44a895d45872546c9290c193643b9df8b5b", + "types": [ + { + "rust_path": "radroots_protocol::radrootsd::transport_publish::v5::AuthCapabilities", + "kind": "struct" + }, + { + "rust_path": "radroots_protocol::radrootsd::transport_publish::v5::Capabilities", + "kind": "struct" + }, + { + "rust_path": "radroots_protocol::radrootsd::transport_publish::v5::CapabilityAvailability", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::radrootsd::transport_publish::v5::CapabilityMaturity", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::radrootsd::transport_publish::v5::DeliveryPolicy", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::radrootsd::transport_publish::v5::DeliveryPolicyName", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::radrootsd::transport_publish::v5::EventRequest", + "kind": "struct" + }, + { + "rust_path": "radroots_protocol::radrootsd::transport_publish::v5::EventResponse", + "kind": "struct" + }, + { + "rust_path": "radroots_protocol::radrootsd::transport_publish::v5::Implementation", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::radrootsd::transport_publish::v5::Job", + "kind": "struct" + }, + { + "rust_path": "radroots_protocol::radrootsd::transport_publish::v5::JobStatus", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::radrootsd::transport_publish::v5::NostrTargetSourcePolicy", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::radrootsd::transport_publish::v5::OperationCapabilities", + "kind": "struct" + }, + { + "rust_path": "radroots_protocol::radrootsd::transport_publish::v5::OutcomeKind", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::radrootsd::transport_publish::v5::ReticulumBehavior", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::radrootsd::transport_publish::v5::SurfaceCapabilities", + "kind": "struct" + }, + { + "rust_path": "radroots_protocol::radrootsd::transport_publish::v5::Target", + "kind": "struct" + }, + { + "rust_path": "radroots_protocol::radrootsd::transport_publish::v5::TargetFingerprint", + "kind": "struct" + }, + { + "rust_path": "radroots_protocol::radrootsd::transport_publish::v5::TargetOutcome", + "kind": "struct" + }, + { + "rust_path": "radroots_protocol::radrootsd::transport_publish::v5::TargetPolicy", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::radrootsd::transport_publish::v5::TargetPolicyName", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::radrootsd::transport_publish::v5::TargetSource", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::radrootsd::transport_publish::v5::TransportCapability", + "kind": "struct" + } + ] + }, + { + "module": "runtime::v1", + "path": "crates/protocol/src/runtime/v1.rs", + "sha256": "d25db1e8b5beaa017bbed549ccc0ce1a54c34f58de4c636b8a33e6a22b66c17f", + "types": [ + { + "rust_path": "radroots_protocol::runtime::v1::ApprovalRequirement", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::runtime::v1::DeadlinePolicy", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::runtime::v1::DryRunSupport", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::runtime::v1::IdempotencyPolicy", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::runtime::v1::Mutability", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::runtime::v1::OperationDescriptor", + "kind": "struct" + }, + { + "rust_path": "radroots_protocol::runtime::v1::OperationId", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::runtime::v1::PrivacyEffect", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::runtime::v1::ProjectionEffect", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::runtime::v1::Risk", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::runtime::v1::SignerRequirement", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::runtime::v1::SyncCapabilityState", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::runtime::v1::SyncHealth", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::runtime::v1::SyncOutboxStatus", + "kind": "struct" + }, + { + "rust_path": "radroots_protocol::runtime::v1::SyncProjectionStatus", + "kind": "struct" + }, + { + "rust_path": "radroots_protocol::runtime::v1::SyncRetryDecision", + "kind": "enum" + }, + { + "rust_path": "radroots_protocol::runtime::v1::SyncStatusReceipt", + "kind": "struct" + }, + { + "rust_path": "radroots_protocol::runtime::v1::TransportRoute", + "kind": "struct" + } + ] + } + ], + "schemas": [ + { + "schema_id": "radroots.protocol.error_report.v1", + "module": "error::v1", + "generation": 1 + }, + { + "schema_id": "radroots.protocol.event_descriptor.v1", + "module": "event::v1", + "generation": 1 + }, + { + "schema_id": "radroots.protocol.reticulum_target.v1", + "module": "capability::v1", + "generation": 1 + }, + { + "schema_id": "radroots.protocol.trade_state.v1", + "module": "event::v1", + "generation": 1 + }, + { + "schema_id": "radroots.protocol.transport_capability_descriptor.v1", + "module": "capability::v1", + "generation": 1 + }, + { + "schema_id": "radroots.protocol.transport_kind.v1", + "module": "capability::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.account.create.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.account.create.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.account.import.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.account.import.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.account.list.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.account.list.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.account.remove.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.account.remove.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.account.select.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.account.select.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.basket.create.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.basket.create.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.basket.get.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.basket.get.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.basket.item.add.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.basket.item.add.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.basket.item.remove.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.basket.item.remove.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.basket.item.update.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.basket.item.update.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.basket.list.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.basket.list.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.basket.quote.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.basket.quote.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.diagnostics.inspect.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.diagnostics.inspect.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.farm.create.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.farm.create.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.farm.get.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.farm.get.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.farm.list.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.farm.list.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.farm.publish.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.farm.publish.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.farm.update.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.farm.update.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.health.inspect.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.health.inspect.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.listing.create.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.listing.create.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.listing.get.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.listing.get.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.listing.list.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.listing.list.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.listing.pause.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.listing.pause.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.listing.publish.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.listing.publish.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.listing.update.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.listing.update.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.listing.withdraw.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.listing.withdraw.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.market.get.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.market.get.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.market.pull.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.market.pull.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.market.search.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.market.search.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.profile.inspect.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.profile.inspect.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.profile.reset.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.profile.reset.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.signer.status.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.signer.status.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.store.backup.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.store.backup.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.store.inspect.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.store.inspect.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.store.restore.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.store.restore.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.sync.pull.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.sync.pull.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.sync.push.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.sync.push.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.sync.status.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.sync.status.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.trade.cancellation.submit.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.trade.cancellation.submit.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.trade.candidate.decide.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.trade.candidate.decide.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.trade.evidence.inspect.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.trade.evidence.inspect.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.trade.evidence.refresh.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.trade.evidence.refresh.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.trade.get.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.trade.get.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.trade.list.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.trade.list.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.trade.operation.resume.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.trade.operation.resume.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.trade.private_artifact.delete.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.trade.private_artifact.delete.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.trade.private_artifact.open.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.trade.private_artifact.open.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.trade.private_artifact.seal.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.trade.private_artifact.seal.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.trade.proposal.submit.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.trade.proposal.submit.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.trade.revision.propose.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.trade.revision.propose.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.transport.capability.list.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.transport.capability.list.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.transport.config.inspect.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.transport.config.inspect.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.transport.config.update.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.transport.config.update.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.transport.delivery.inspect.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.transport.delivery.inspect.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.transport.delivery.retry.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.transport.delivery.retry.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.transport.status.inspect.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.transport.status.inspect.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.validation.status.receipt.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radroots.runtime.validation.status.request.v1", + "module": "runtime::v1", + "generation": 1 + }, + { + "schema_id": "radrootsd.transport_publish.v5", + "module": "radrootsd::transport_publish::v5", + "generation": 5 + } + ] +} diff --git a/crates/protocol/tests/fixtures/wire_values.v1.json b/crates/protocol/tests/fixtures/wire_values.v1.json @@ -0,0 +1,153 @@ +{ + "suite": "protocol_wire_values_v1", + "contract_version": "1.0.0", + "vectors": [ + { + "id": "protocol_capability_transport_kind_001", + "kind": "protocol.capability.transport_kind", + "input": "reticulum", + "expected": "reticulum" + }, + { + "id": "protocol_capability_reticulum_target_002", + "kind": "protocol.capability.reticulum_target", + "input": { + "destination": { "canonical": "a1b2c3d4" }, + "mesh_scope": { "value": "farm.mesh-1" } + }, + "expected": { + "destination": { "canonical": "a1b2c3d4" }, + "mesh_scope": { "value": "farm.mesh-1" } + } + }, + { + "id": "protocol_event_class_003", + "kind": "protocol.event.event_class", + "input": "unsigned_rumor", + "expected": "unsigned_rumor" + }, + { + "id": "protocol_trade_state_004", + "kind": "protocol.event.trade_state", + "input": "agreed_pending_validation", + "expected": "agreed_pending_validation" + }, + { + "id": "protocol_runtime_operation_id_005", + "kind": "protocol.runtime.operation_id", + "input": "sync.push", + "expected": "sync.push" + }, + { + "id": "protocol_runtime_risk_006", + "kind": "protocol.runtime.risk", + "input": "critical", + "expected": "critical" + }, + { + "id": "protocol_runtime_transport_route_007", + "kind": "protocol.runtime.transport_route", + "input": { + "local": true, + "nostr": true, + "reticulum": false, + "deliver": true, + "fetch": false, + "synchronize": true, + "diagnostics": false + }, + "expected": { + "local": true, + "nostr": true, + "reticulum": false, + "deliver": true, + "fetch": false, + "synchronize": true, + "diagnostics": false + } + }, + { + "id": "protocol_daemon_target_policy_008", + "kind": "protocol.radrootsd.target_policy", + "input": { + "kind": "nostr", + "source_policy": "explicit_only", + "relay_urls": [] + }, + "expected": { + "kind": "nostr", + "source_policy": "explicit_only", + "relay_urls": [] + } + }, + { + "id": "protocol_daemon_delivery_policy_009", + "kind": "protocol.radrootsd.delivery_policy", + "input": { "mode": "quorum", "quorum": 2 }, + "expected": { "mode": "quorum", "quorum": 2 } + }, + { + "id": "protocol_error_report_010", + "kind": "protocol.error.report", + "input": { + "schema_version": 1, + "code": "relay_rate_limited", + "class": "network", + "retryable": true, + "recovery_actions": ["retry_after_transport_failure"], + "operation_id": "sync.push", + "capability_id": "nostr", + "message": "Relay rate limit requires a later retry", + "details": [] + }, + "expected": { + "schema_version": 1, + "code": "relay_rate_limited", + "class": "network", + "retryable": true, + "recovery_actions": ["retry_after_transport_failure"], + "operation_id": "sync.push", + "capability_id": "nostr", + "message": "Relay rate limit requires a later retry", + "details": [] + } + }, + { + "id": "protocol_runtime_unknown_operation_011", + "kind": "protocol.runtime.operation_id", + "input": "runtime.unknown", + "expected_error_contains": "unknown operation id" + }, + { + "id": "protocol_runtime_route_unknown_field_012", + "kind": "protocol.runtime.transport_route", + "input": { + "local": true, + "nostr": false, + "reticulum": false, + "deliver": false, + "fetch": false, + "synchronize": false, + "diagnostics": false, + "executor": "forbidden" + }, + "expected_error_contains": "unknown field" + }, + { + "id": "protocol_error_report_version_013", + "kind": "protocol.error.report", + "input": { + "schema_version": 2, + "code": "relay_rate_limited", + "class": "network", + "retryable": true, + "recovery_actions": ["retry_after_transport_failure"], + "operation_id": "sync.push", + "capability_id": "nostr", + "message": "Relay rate limit requires a later retry", + "details": [] + }, + "expected_error_contains": "unsupported error report schema version 2" + } + ] +} diff --git a/crates/secrets/Cargo.toml b/crates/secrets/Cargo.toml @@ -13,7 +13,7 @@ documentation = "https://docs.rs/radroots_secrets" publish = ["crates-io"] keywords = ["radroots", "secrets", "encryption", "keyring"] categories = ["cryptography", "no-std"] -include = ["src/**", "tests/**", "examples/**", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] +include = ["src/**", "tests/**", "!tests/consumer_migration.rs", "!tests/package_boundary.rs", "!tests/security_contract.rs", "examples/**", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] [package.metadata.docs.rs] features = ["std", "serde", "memory", "file"] diff --git a/crates/signing/Cargo.toml b/crates/signing/Cargo.toml @@ -13,7 +13,7 @@ documentation = "https://docs.rs/radroots_signing" publish = ["crates-io"] keywords = ["radroots", "signing", "nostr", "authorization"] categories = ["cryptography", "no-std"] -include = ["src/**", "tests/**", "examples/**", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] +include = ["src/**", "tests/**", "!tests/package_boundary.rs", "examples/**", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] [package.metadata.docs.rs] features = ["std", "serde"] diff --git a/crates/storage/Cargo.toml b/crates/storage/Cargo.toml @@ -13,7 +13,7 @@ publish = ["crates-io"] documentation = "https://docs.rs/radroots_storage" keywords = ["radroots", "storage", "persistence", "events"] categories = ["database", "data-structures", "no-std"] -include = ["src/**", "tests/**", "examples/**", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] +include = ["src/**", "tests/**", "!tests/legacy_quarantine.rs", "!tests/package_boundary.rs", "!tests/workspace_consumers.rs", "examples/**", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] [package.metadata.docs.rs] features = ["memory", "serde"] diff --git a/crates/storage_sqlite/Cargo.toml b/crates/storage_sqlite/Cargo.toml @@ -13,7 +13,7 @@ publish = ["crates-io"] documentation = "https://docs.rs/radroots_storage_sqlite" keywords = ["radroots", "sqlite", "storage", "database"] categories = ["database"] -include = ["src/**", "tests/**", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] +include = ["src/**", "tests/**", "!tests/package_boundary.rs", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] [package.metadata.docs.rs] features = [] diff --git a/crates/sync/Cargo.toml b/crates/sync/Cargo.toml @@ -13,7 +13,7 @@ publish = ["crates-io"] documentation = "https://docs.rs/radroots_sync" keywords = ["radroots", "synchronization", "outbox", "events"] categories = ["asynchronous", "data-structures", "no-std"] -include = ["src/**", "tests/**", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] +include = ["src/**", "tests/**", "!tests/package_boundary.rs", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] [package.metadata.docs.rs] features = ["serde"] diff --git a/crates/trade/Cargo.toml b/crates/trade/Cargo.toml @@ -13,7 +13,7 @@ documentation = "https://docs.rs/radroots_trade" readme = "README.md" keywords = ["radroots", "trade", "local-food", "workflow"] categories = ["algorithms", "data-structures", "no-std"] -include = ["src/**", "tests/**", "examples/**", "Cargo.toml", "README.md", "COMPATIBILITY.md", "LICENSE-APACHE", "LICENSE-MIT"] +include = ["src/**", "tests/**", "!tests/package_boundary.rs", "examples/**", "Cargo.toml", "README.md", "COMPATIBILITY.md", "LICENSE-APACHE", "LICENSE-MIT"] [package.metadata.docs.rs] features = ["std", "serde", "json"] diff --git a/crates/transport/Cargo.toml b/crates/transport/Cargo.toml @@ -13,7 +13,7 @@ readme = "README.md" documentation = "https://docs.rs/radroots_transport" keywords = ["radroots", "transport", "async", "networking"] categories = ["asynchronous", "network-programming", "no-std"] -include = ["src/**", "tests/**", "examples/**", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] +include = ["src/**", "tests/**", "!tests/package_boundary.rs", "!tests/source_boundary.rs", "examples/**", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] [package.metadata.docs.rs] features = ["std", "serde"] diff --git a/crates/transport/tests/fixtures/target_uri.v1.json b/crates/transport/tests/fixtures/target_uri.v1.json @@ -0,0 +1,76 @@ +{ + "suite": "transport", + "contract_version": "1.0.0", + "vectors": [ + { + "id": "transport_target_uri_generic_canonical_001", + "kind": "transport.target_uri.valid", + "input": { + "uri": "MESH://Node.Example/path?q=1#frag" + }, + "expected": { + "canonical_uri": "mesh://node.example/path?q=1#frag" + } + }, + { + "id": "transport_target_uri_empty_002", + "kind": "transport.target_uri.invalid", + "input": { + "uri": " " + }, + "expected": { + "error": "empty_target_uri" + } + }, + { + "id": "transport_target_uri_whitespace_003", + "kind": "transport.target_uri.invalid", + "input": { + "uri": "bad target" + }, + "expected": { + "error": "invalid_target_uri" + } + }, + { + "id": "transport_target_uri_bad_scheme_004", + "kind": "transport.target_uri.invalid", + "input": { + "uri": "1bad:target" + }, + "expected": { + "error": "invalid_target_uri" + } + }, + { + "id": "transport_nostr_relay_canonical_005", + "kind": "transport.nostr_relay_target.valid", + "input": { + "uri": "WSS://Relay.Example/" + }, + "expected": { + "canonical_uri": "wss://relay.example" + } + }, + { + "id": "transport_nostr_relay_query_006", + "kind": "transport.nostr_relay_target.invalid", + "input": { + "uri": "wss://relay.example?subscription=1" + }, + "expected": { + "error": "invalid_target_uri" + } + }, + { + "id": "transport_nostr_relay_nonlocal_ws_007", + "kind": "transport.nostr_relay_target.invalid", + "input": { + "uri": "ws://relay.example" + }, + "expected": { + "error": "invalid_target_uri" + } + } + ] +} diff --git a/crates/transport/tests/transport.rs b/crates/transport/tests/transport.rs @@ -586,8 +586,7 @@ fn transport_kind_and_target_parsers_cover_negative_edges() { #[test] fn checked_in_transport_target_uri_vectors_match_parser_behavior() { - let vectors = - include_str!("../../../contracts/conformance/vectors/transport/target_uri.v1.json"); + let vectors = include_str!("fixtures/target_uri.v1.json"); let document: Value = serde_json::from_str(vectors).expect("transport target vector json"); let entries = document .get("vectors") diff --git a/crates/transport_nostr/Cargo.toml b/crates/transport_nostr/Cargo.toml @@ -13,7 +13,7 @@ readme = "README.md" documentation = "https://docs.rs/radroots_transport_nostr" keywords = ["radroots", "nostr", "transport", "websocket"] categories = ["asynchronous", "network-programming"] -include = ["src/**", "tests/**", "examples/**", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] +include = ["src/**", "tests/**", "!tests/legacy_quarantine.rs", "!tests/network_hardening.rs", "!tests/package_boundary.rs", "!tests/workspace_consumers.rs", "examples/**", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] [package.metadata.docs.rs] features = []