commit 67b85e49a8c5870422ae5cf90f2488385ced1bd1 parent ee542a3333fee6e8a0c801777a547d78e182eba1 Author: triesap <tyson@radroots.org> Date: Tue, 28 Jul 2026 05:49:52 +0000 identity: migrate workspace consumers - Replace legacy identity wrappers with canonical public value types. - Move local signing ownership to concrete Nostr key containers. - Migrate conformance fixtures, stores, and protocol consumers. - Validate workspace boundaries and the canonical release contract. Diffstat:
134 files changed, 2782 insertions(+), 2127 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock @@ -4499,6 +4499,7 @@ name = "radroots_authority" version = "1.0.0-alpha.1" dependencies = [ "radroots_event", + "radroots_identity", "radroots_nostr", "serde_json", ] @@ -4553,6 +4554,7 @@ dependencies = [ "radroots_blossom", "radroots_core", "radroots_event", + "radroots_identity", "radroots_test_fixtures", "serde", "serde_json", @@ -4579,6 +4581,7 @@ dependencies = [ "radroots_blossom", "radroots_event", "radroots_event_codec", + "radroots_identity", "radroots_transport", "serde", "serde_json", @@ -4706,6 +4709,7 @@ dependencies = [ name = "radroots_nostr_accounts" version = "1.0.0-alpha.1" dependencies = [ + "nostr", "radroots_identity", "radroots_nostr_signer", "radroots_nostrdb", @@ -4785,6 +4789,7 @@ dependencies = [ "hex", "radroots_event", "radroots_event_store", + "radroots_identity", "radroots_nostr", "radroots_transport", "serde", @@ -5103,6 +5108,7 @@ dependencies = [ "radroots_event", "radroots_event_codec", "radroots_event_store", + "radroots_identity", "radroots_nostr", "radroots_test_fixtures", "radroots_transport", diff --git a/contracts/conformance/schema/vector.schema.json b/contracts/conformance/schema/vector.schema.json @@ -24,8 +24,7 @@ "required": [ "id", "kind", - "input", - "expected" + "input" ], "properties": { "id": { @@ -37,8 +36,34 @@ "minLength": 1 }, "input": {}, - "expected": {} + "expected": {}, + "expected_error_contains": { + "type": "string", + "minLength": 1 + } }, + "oneOf": [ + { + "required": [ + "expected" + ], + "not": { + "required": [ + "expected_error_contains" + ] + } + }, + { + "required": [ + "expected_error_contains" + ], + "not": { + "required": [ + "expected" + ] + } + } + ], "additionalProperties": false } } diff --git a/contracts/conformance/vectors/calendar/nip52_baseline.v1.json b/contracts/conformance/vectors/calendar/nip52_baseline.v1.json @@ -42,13 +42,13 @@ ["g", "C23NB62W20ST"], ["summary", " Weekly pickup "], ["image", "https://ordinary.example.test/images/market.jpg?size=large"], - ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - ["p", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "wss://relay.example.test/events"], - ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "", " host "], + ["p", "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df"], + ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "wss://relay.example.test/events"], + ["p", "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "", " host "], ["t", "vegetables"], ["t", "CSA"], ["r", "ipfs://bafybeigdyrzt/reference"], - ["a", "31924:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-calendar", "wss://relay.example.test"], + ["a", "31924:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-calendar", "wss://relay.example.test"], ["name", "Deprecated display name"], ["D", "extension", "preserved"] ] @@ -64,14 +64,14 @@ "summary": " Weekly pickup ", "image": "https://ordinary.example.test/images/market.jpg?size=large", "participants": [ - {"pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "relay": null, "role": null}, - {"pubkey": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "relay": "wss://relay.example.test/events", "role": null}, - {"pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "relay": null, "role": " host "} + {"pubkey": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "relay": null, "role": null}, + {"pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": "wss://relay.example.test/events", "role": null}, + {"pubkey": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "relay": null, "role": " host "} ], "categories": ["vegetables", "CSA"], "references": ["ipfs://bafybeigdyrzt/reference"], "calendar_requests": [ - {"calendar": "31924:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-calendar", "relay": "wss://relay.example.test"} + {"calendar": "31924:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-calendar", "relay": "wss://relay.example.test"} ], "legacy_name": "Deprecated display name", "date_day_extensions": [["D", "extension", "preserved"]] @@ -150,7 +150,7 @@ "input": { "kind": 31922, "content": "", - "tags": [["d", "bad-participant"], ["title", "Bad participant"], ["start", "2026-06-20"], ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", ""]] + "tags": [["d", "bad-participant"], ["title", "Bad participant"], ["start", "2026-06-20"], ["p", "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", ""]] }, "expected": { "error": "invalid_tag", "tag": "p" } }, @@ -160,7 +160,7 @@ "input": { "kind": 31922, "content": "", - "tags": [["d", "bad-request"], ["title", "Bad request"], ["start", "2026-06-20"], ["a", "31923:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:not-a-calendar"]] + "tags": [["d", "bad-request"], ["title", "Bad request"], ["start", "2026-06-20"], ["a", "31923:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:not-a-calendar"]] }, "expected": { "error": "invalid_tag", "tag": "a" } }, @@ -357,8 +357,8 @@ ["title", "Regional farm calendar"], ["description", "NIP-51 client-facing set description"], ["image", "https://ordinary.example.test/calendars/victoria.jpg"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:moss-street-market", "wss://date-relay.example.test/events"], - ["a", "31923:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:harvest-window", "WSS://Time-Relay.Example.Test/events"] + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:moss-street-market", "wss://date-relay.example.test/events"], + ["a", "31923:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:harvest-window", "WSS://Time-Relay.Example.Test/events"] ] }, "expected": { @@ -369,11 +369,11 @@ "image": "https://ordinary.example.test/calendars/victoria.jpg", "event_references": [ { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:moss-street-market", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:moss-street-market", "relay": "wss://date-relay.example.test/events" }, { - "coordinate": "31923:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:harvest-window", + "coordinate": "31923:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:harvest-window", "relay": "WSS://Time-Relay.Example.Test/events" } ] @@ -388,7 +388,7 @@ "tags": [ ["d", "uppercase-observed"], ["title", "Uppercase observed"], - ["a", "31922:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB:farm-tour", "WSS://Relay.Example.Test/events"] + ["a", "31922:585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF:farm-tour", "WSS://Relay.Example.Test/events"] ] }, "expected": { @@ -399,7 +399,7 @@ "image": null, "event_references": [ { - "coordinate": "31922:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB:farm-tour", + "coordinate": "31922:585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF:farm-tour", "relay": "WSS://Relay.Example.Test/events" } ] @@ -414,8 +414,8 @@ "tags": [ ["d", "duplicates-observed"], ["title", "Duplicates observed"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour", "wss://one.example.test"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour", "wss://two.example.test"] + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour", "wss://one.example.test"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour", "wss://two.example.test"] ] }, "expected": { @@ -426,11 +426,11 @@ "image": null, "event_references": [ { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour", "relay": "wss://one.example.test" }, { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour", "relay": "wss://two.example.test" } ] @@ -497,7 +497,7 @@ "tags": [ ["d", "bad-a-arity"], ["title", "Bad a arity"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour", "wss://relay.example.test", "unexpected"] + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour", "wss://relay.example.test", "unexpected"] ] }, "expected": {"error": "invalid_tag", "tag": "a"} @@ -518,7 +518,7 @@ "input": { "kind": 31924, "content": "", - "tags": [["d", "wrong-coordinate-kind"], ["title", "Wrong coordinate kind"], ["a", "31924:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:another-calendar"]] + "tags": [["d", "wrong-coordinate-kind"], ["title", "Wrong coordinate kind"], ["a", "31924:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:another-calendar"]] }, "expected": {"error": "invalid_tag", "tag": "a"} }, @@ -531,7 +531,7 @@ "tags": [ ["d", "bad-relay"], ["title", "Bad relay"], - ["a", "31923:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:harvest-window", "https://relay.example.test"] + ["a", "31923:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:harvest-window", "https://relay.example.test"] ] }, "expected": {"error": "invalid_tag", "tag": "a"} @@ -554,14 +554,14 @@ "content": "", "tags": [ ["d", "farm-tour-rsvp"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["status", "accepted"] ] }, "expected": { "d": "farm-tour-rsvp", "event_reference": { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour", "relay": null }, "revision_reference": null, @@ -580,28 +580,28 @@ "content": "I can help at the produce table.", "tags": [ ["d", "market-rsvp"], - ["a", "31923:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:market-shift", "wss://coordinate-relay.example.test/events"], - ["e", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "wss://event-relay.example.test/events"], + ["a", "31923:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:market-shift", "wss://coordinate-relay.example.test/events"], + ["e", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "wss://event-relay.example.test/events"], ["status", "tentative"], ["fb", "busy"], - ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "wss://author-relay.example.test/events"] + ["p", "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "wss://author-relay.example.test/events"] ] }, "expected": { "d": "market-rsvp", "event_reference": { - "coordinate": "31923:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:market-shift", + "coordinate": "31923:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:market-shift", "relay": "wss://coordinate-relay.example.test/events" }, "revision_reference": { - "id": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "id": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": "wss://event-relay.example.test/events" }, "status": "tentative", "observed_free_busy": "busy", "effective_free_busy": "busy", "author_hint": { - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "pubkey": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "relay": "wss://author-relay.example.test/events" }, "note": "I can help at the produce table." @@ -615,7 +615,7 @@ "content": "Unable to attend.", "tags": [ ["d", "declined-rsvp"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:seed-swap"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:seed-swap"], ["status", "declined"], ["fb", "busy"] ] @@ -623,7 +623,7 @@ "expected": { "d": "declined-rsvp", "event_reference": { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:seed-swap", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:seed-swap", "relay": null }, "revision_reference": null, @@ -642,28 +642,28 @@ "content": "", "tags": [ ["d", "uppercase-rsvp"], - ["a", "31922:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB:farm-tour", "WSS://Coordinate-Relay.Example.Test/events"], - ["e", "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC", "WSS://Event-Relay.Example.Test/events"], + ["a", "31922:585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF:farm-tour", "WSS://Coordinate-Relay.Example.Test/events"], + ["e", "E0266E3CFB0D2886F91C73F5F868F3B98273713E5FCD97C081663F5518A4B3AF", "WSS://Event-Relay.Example.Test/events"], ["status", "accepted"], ["fb", "free"], - ["p", "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", "WSS://Author-Relay.Example.Test/events"] + ["p", "585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF", "WSS://Author-Relay.Example.Test/events"] ] }, "expected": { "d": "uppercase-rsvp", "event_reference": { - "coordinate": "31922:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB:farm-tour", + "coordinate": "31922:585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF:farm-tour", "relay": "WSS://Coordinate-Relay.Example.Test/events" }, "revision_reference": { - "id": "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC", + "id": "E0266E3CFB0D2886F91C73F5F868F3B98273713E5FCD97C081663F5518A4B3AF", "relay": "WSS://Event-Relay.Example.Test/events" }, "status": "accepted", "observed_free_busy": "free", "effective_free_busy": "free", "author_hint": { - "pubkey": "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", + "pubkey": "585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF", "relay": "WSS://Author-Relay.Example.Test/events" }, "note": null @@ -675,7 +675,7 @@ "input": { "kind": 31925, "content": "", - "tags": [["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], ["status", "accepted"]] + "tags": [["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["status", "accepted"]] }, "expected": {"error": "missing_tag", "tag": "d"} }, @@ -691,7 +691,7 @@ "input": { "kind": 31925, "content": "", - "tags": [["d", "missing-status"], ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"]] + "tags": [["d", "missing-status"], ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"]] }, "expected": {"error": "missing_tag", "tag": "status"} }, @@ -701,7 +701,7 @@ "input": { "kind": 31925, "content": "", - "tags": [["d", "one"], ["d", "two"], ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], ["status", "accepted"]] + "tags": [["d", "one"], ["d", "two"], ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["status", "accepted"]] }, "expected": {"error": "duplicate_tag", "tag": "d"} }, @@ -713,8 +713,8 @@ "content": "", "tags": [ ["d", "duplicate-a"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], - ["a", "31923:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-shift"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], + ["a", "31923:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-shift"], ["status", "accepted"] ] }, @@ -726,7 +726,7 @@ "input": { "kind": 31925, "content": "", - "tags": [["d", "duplicate-status"], ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], ["status", "accepted"], ["status", "tentative"]] + "tags": [["d", "duplicate-status"], ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["status", "accepted"], ["status", "tentative"]] }, "expected": {"error": "duplicate_tag", "tag": "status"} }, @@ -738,8 +738,8 @@ "content": "", "tags": [ ["d", "duplicate-e"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], - ["e", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], + ["e", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], ["e", "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"], ["status", "accepted"] ] @@ -752,7 +752,7 @@ "input": { "kind": 31925, "content": "", - "tags": [["d", "duplicate-fb"], ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], ["status", "accepted"], ["fb", "free"], ["fb", "busy"]] + "tags": [["d", "duplicate-fb"], ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["status", "accepted"], ["fb", "free"], ["fb", "busy"]] }, "expected": {"error": "duplicate_tag", "tag": "fb"} }, @@ -764,10 +764,10 @@ "content": "", "tags": [ ["d", "duplicate-p"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["status", "accepted"], - ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - ["p", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"] + ["p", "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df"], + ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"] ] }, "expected": {"error": "duplicate_tag", "tag": "p"} @@ -780,7 +780,7 @@ "content": "", "tags": [ ["d", "bad-a-arity"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour", "wss://relay.example.test", "unexpected"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour", "wss://relay.example.test", "unexpected"], ["status", "accepted"] ] }, @@ -794,8 +794,8 @@ "content": "", "tags": [ ["d", "bad-e-arity"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], - ["e", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "wss://relay.example.test", "unexpected"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], + ["e", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "wss://relay.example.test", "unexpected"], ["status", "accepted"] ] }, @@ -809,9 +809,9 @@ "content": "", "tags": [ ["d", "bad-p-role"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["status", "accepted"], - ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "wss://relay.example.test", "host"] + ["p", "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "wss://relay.example.test", "host"] ] }, "expected": {"error": "invalid_tag", "tag": "p"} @@ -822,7 +822,7 @@ "input": { "kind": 31925, "content": "", - "tags": [["d", "wrong-kind"], ["a", "31924:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-calendar"], ["status", "accepted"]] + "tags": [["d", "wrong-kind"], ["a", "31924:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-calendar"], ["status", "accepted"]] }, "expected": {"error": "invalid_tag", "tag": "a"} }, @@ -838,7 +838,7 @@ "input": { "kind": 31925, "content": "", - "tags": [["d", "bad-event-id"], ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], ["e", "not-an-event-id"], ["status", "accepted"]] + "tags": [["d", "bad-event-id"], ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["e", "not-an-event-id"], ["status", "accepted"]] }, "expected": {"error": "invalid_tag", "tag": "e"} }, @@ -848,7 +848,7 @@ "input": { "kind": 31925, "content": "", - "tags": [["d", "bad-author"], ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], ["status", "accepted"], ["p", "not-a-pubkey"]] + "tags": [["d", "bad-author"], ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["status", "accepted"], ["p", "not-a-pubkey"]] }, "expected": {"error": "invalid_tag", "tag": "p"} }, @@ -858,7 +858,7 @@ "input": { "kind": 31925, "content": "", - "tags": [["d", "bad-a-relay"], ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour", "https://relay.example.test"], ["status", "accepted"]] + "tags": [["d", "bad-a-relay"], ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour", "https://relay.example.test"], ["status", "accepted"]] }, "expected": {"error": "invalid_tag", "tag": "a"} }, @@ -868,7 +868,7 @@ "input": { "kind": 31925, "content": "", - "tags": [["d", "bad-e-relay"], ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], ["e", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "https://relay.example.test"], ["status", "accepted"]] + "tags": [["d", "bad-e-relay"], ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["e", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "https://relay.example.test"], ["status", "accepted"]] }, "expected": {"error": "invalid_tag", "tag": "e"} }, @@ -878,7 +878,7 @@ "input": { "kind": 31925, "content": "", - "tags": [["d", "bad-p-relay"], ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], ["status", "accepted"], ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "https://relay.example.test"]] + "tags": [["d", "bad-p-relay"], ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["status", "accepted"], ["p", "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "https://relay.example.test"]] }, "expected": {"error": "invalid_tag", "tag": "p"} }, @@ -888,7 +888,7 @@ "input": { "kind": 31925, "content": "", - "tags": [["d", "bad-status"], ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], ["status", "maybe"]] + "tags": [["d", "bad-status"], ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["status", "maybe"]] }, "expected": {"error": "invalid_tag", "tag": "status"} }, @@ -898,7 +898,7 @@ "input": { "kind": 31925, "content": "", - "tags": [["d", "bad-fb"], ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], ["status", "accepted"], ["fb", "unknown"]] + "tags": [["d", "bad-fb"], ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["status", "accepted"], ["fb", "unknown"]] }, "expected": {"error": "invalid_tag", "tag": "fb"} }, @@ -960,7 +960,7 @@ "content": "", "tags": [ ["d", "bad-status-arity"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["status", "accepted", "unexpected"] ] }, @@ -974,7 +974,7 @@ "content": "", "tags": [ ["d", "bad-fb-arity"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["status", "accepted"], ["fb", "free", "unexpected"] ] diff --git a/contracts/conformance/vectors/calendar/radroots_profile.v1.json b/contracts/conformance/vectors/calendar/radroots_profile.v1.json @@ -49,12 +49,12 @@ } }, "participants": [ - {"pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "relay": "wss://relay.example.test", "role": "host"} + {"pubkey": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "relay": "wss://relay.example.test", "role": "host"} ], "categories": ["csa", "vegetables"], "references": ["https://example.test/pickup-details"], "calendar_requests": [ - {"calendar": "31924:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-calendar", "relay": "wss://relay.example.test"} + {"calendar": "31924:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-calendar", "relay": "wss://relay.example.test"} ] }, "expected": { @@ -71,11 +71,11 @@ ["g", "c23nb62w20st"], ["summary", "Weekly pickup"], ["image", "https://media.example/aba72b48bb536e341ab81c5f86053981c443029766a4374ee86a4f56577ebc84.webp"], - ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "wss://relay.example.test", "host"], + ["p", "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "wss://relay.example.test", "host"], ["t", "csa"], ["t", "vegetables"], ["r", "https://example.test/pickup-details"], - ["a", "31924:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-calendar", "wss://relay.example.test"] + ["a", "31924:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-calendar", "wss://relay.example.test"] ] }, "media_verification": "byte_verified", @@ -188,7 +188,7 @@ "input": { "kind": 31922, "content": "", - "tags": [["d", "farm-tour"], ["title", "Urban farm tour"], ["start", "2026-07-18"], ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "WSS://relay.example.test"]] + "tags": [["d", "farm-tour"], ["title", "Urban farm tour"], ["start", "2026-07-18"], ["p", "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "WSS://relay.example.test"]] }, "expected": {"error": "non_canonical_field"} }, @@ -278,11 +278,11 @@ "list_description": "NIP-51 set description for compatible clients.", "event_references": [ { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": "wss://date-relay.example.test/events" }, { - "coordinate": "31923:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:CCCCCCCCCCCCCCCCCCCCCg", + "coordinate": "31923:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:CCCCCCCCCCCCCCCCCCCCCg", "relay": "wss://time-relay.example.test/events" } ] @@ -294,8 +294,8 @@ "tags": [ ["d", "AAAAAAAAAAAAAAAAAAAAAA"], ["title", "South Island farm schedule"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", "wss://date-relay.example.test/events"], - ["a", "31923:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:CCCCCCCCCCCCCCCCCCCCCg", "wss://time-relay.example.test/events"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "wss://date-relay.example.test/events"], + ["a", "31923:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:CCCCCCCCCCCCCCCCCCCCCg", "wss://time-relay.example.test/events"], ["description", "NIP-51 set description for compatible clients."] ] } @@ -320,7 +320,7 @@ }, "event_references": [ { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": null } ] @@ -332,7 +332,7 @@ "tags": [ ["d", "AAAAAAAAAAAAAAAAAAAAAA"], ["title", "Victoria farm calendar"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ"], ["image", "https://media.example/aba72b48bb536e341ab81c5f86053981c443029766a4374ee86a4f56577ebc84.webp"] ] }, @@ -360,11 +360,11 @@ "title": "Duplicate event calendar", "event_references": [ { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": "wss://one.example.test" }, { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": "wss://two.example.test" } ] @@ -379,7 +379,7 @@ "title": "Uppercase relay", "event_references": [ { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": "WSS://Relay.Example.Test/events" } ] @@ -394,7 +394,7 @@ "title": "Wrong coordinate kind", "event_references": [ { - "coordinate": "31924:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31924:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": null } ] @@ -410,8 +410,8 @@ "image": { "bytes_utf8": "victoria-calendar", "descriptor": { - "url": "https://media.example/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.webp", - "sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "url": "https://media.example/585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df.webp", + "sha256": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "size": 17, "type": "image/webp", "uploaded": 1784347200 @@ -444,8 +444,8 @@ "tags": [ ["d", "AAAAAAAAAAAAAAAAAAAAAA"], ["title", "South Island farm schedule"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", "wss://date-relay.example.test/events"], - ["a", "31923:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:CCCCCCCCCCCCCCCCCCCCCg", "wss://time-relay.example.test/events"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "wss://date-relay.example.test/events"], + ["a", "31923:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:CCCCCCCCCCCCCCCCCCCCCg", "wss://time-relay.example.test/events"], ["description", "NIP-51 set description for compatible clients."], ["image", "https://media.example/aba72b48bb536e341ab81c5f86053981c443029766a4374ee86a4f56577ebc84.webp"] ] @@ -456,11 +456,11 @@ "list_description": "NIP-51 set description for compatible clients.", "event_references": [ { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": "wss://date-relay.example.test/events" }, { - "coordinate": "31923:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:CCCCCCCCCCCCCCCCCCCCCg", + "coordinate": "31923:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:CCCCCCCCCCCCCCCCCCCCCg", "relay": "wss://time-relay.example.test/events" } ], @@ -477,7 +477,7 @@ "tags": [ ["d", "AAAAAAAAAAAAAAAAAAAAAA"], ["title", "Uppercase reference"], - ["a", "31922:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB:BBBBBBBBBBBBBBBBBBBBBQ", "WSS://Relay.Example.Test/events"] + ["a", "31922:585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF:BBBBBBBBBBBBBBBBBBBBBQ", "WSS://Relay.Example.Test/events"] ] }, "expected": {"error": "non_canonical_field", "field": "event_reference"} @@ -491,8 +491,8 @@ "tags": [ ["d", "AAAAAAAAAAAAAAAAAAAAAA"], ["title", "Duplicate reference"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", "wss://one.example.test"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", "wss://two.example.test"] + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "wss://one.example.test"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "wss://two.example.test"] ] }, "expected": {"error": "duplicate_event_reference"} @@ -527,7 +527,7 @@ "input": { "d": "DDDDDDDDDDDDDDDDDDDDDw", "event_reference": { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": null }, "status": "accepted" @@ -538,7 +538,7 @@ "content": "", "tags": [ ["d", "DDDDDDDDDDDDDDDDDDDDDw"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ"], ["status", "accepted"] ] } @@ -550,17 +550,17 @@ "input": { "d": "DDDDDDDDDDDDDDDDDDDDDw", "event_reference": { - "coordinate": "31923:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31923:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": "wss://coordinate-relay.example.test/events" }, "revision_reference": { - "id": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "id": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": "wss://event-relay.example.test/events" }, "status": "tentative", "free_busy": "busy", "author_hint": { - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "pubkey": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "relay": "wss://author-relay.example.test/events" }, "note": "I can help with the wash-pack shift." @@ -571,11 +571,11 @@ "content": "I can help with the wash-pack shift.", "tags": [ ["d", "DDDDDDDDDDDDDDDDDDDDDw"], - ["a", "31923:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", "wss://coordinate-relay.example.test/events"], + ["a", "31923:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "wss://coordinate-relay.example.test/events"], ["status", "tentative"], - ["e", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "wss://event-relay.example.test/events"], + ["e", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "wss://event-relay.example.test/events"], ["fb", "busy"], - ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "wss://author-relay.example.test/events"] + ["p", "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "wss://author-relay.example.test/events"] ] }, "observed_free_busy": "busy", @@ -588,7 +588,7 @@ "input": { "d": "DDDDDDDDDDDDDDDDDDDDDw", "event_reference": { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": null }, "status": "declined", @@ -602,7 +602,7 @@ "input": { "d": "farm-tour-rsvp", "event_reference": { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": null }, "status": "accepted" @@ -615,11 +615,11 @@ "input": { "d": "DDDDDDDDDDDDDDDDDDDDDw", "event_reference": { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": null }, "revision_reference": { - "id": "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC", + "id": "E0266E3CFB0D2886F91C73F5F868F3B98273713E5FCD97C081663F5518A4B3AF", "relay": null }, "status": "accepted" @@ -632,12 +632,12 @@ "input": { "d": "DDDDDDDDDDDDDDDDDDDDDw", "event_reference": { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": null }, "status": "accepted", "author_hint": { - "pubkey": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null } }, @@ -649,7 +649,7 @@ "input": { "d": "DDDDDDDDDDDDDDDDDDDDDw", "event_reference": { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": "WSS://Relay.Example.Test/events" }, "status": "accepted" @@ -662,7 +662,7 @@ "input": { "d": "DDDDDDDDDDDDDDDDDDDDDw", "event_reference": { - "coordinate": "31924:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31924:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": null }, "status": "accepted" @@ -677,7 +677,7 @@ "content": "", "tags": [ ["d", "DDDDDDDDDDDDDDDDDDDDDw"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ"], ["status", "accepted"] ] }, @@ -696,25 +696,25 @@ "content": "I can help with the wash-pack shift.", "tags": [ ["d", "DDDDDDDDDDDDDDDDDDDDDw"], - ["a", "31923:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", "wss://coordinate-relay.example.test/events"], - ["e", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "wss://event-relay.example.test/events"], + ["a", "31923:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "wss://coordinate-relay.example.test/events"], + ["e", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "wss://event-relay.example.test/events"], ["status", "tentative"], ["fb", "busy"], - ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "wss://author-relay.example.test/events"] + ["p", "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "wss://author-relay.example.test/events"] ] }, "expected": { "d": "DDDDDDDDDDDDDDDDDDDDDw", "event_reference": { - "coordinate": "31923:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31923:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": "wss://coordinate-relay.example.test/events" }, "revision_reference": { - "id": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "id": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": "wss://event-relay.example.test/events" }, "author_hint": { - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "pubkey": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "relay": "wss://author-relay.example.test/events" }, "status": "tentative", @@ -730,7 +730,7 @@ "content": "Unable to attend.", "tags": [ ["d", "DDDDDDDDDDDDDDDDDDDDDw"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ"], ["status", "declined"], ["fb", "busy"] ] @@ -750,10 +750,10 @@ "content": "", "tags": [ ["d", "DDDDDDDDDDDDDDDDDDDDDw"], - ["a", "31922:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB:BBBBBBBBBBBBBBBBBBBBBQ", "WSS://Coordinate-Relay.Example.Test/events"], - ["e", "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC", "WSS://Event-Relay.Example.Test/events"], + ["a", "31922:585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF:BBBBBBBBBBBBBBBBBBBBBQ", "WSS://Coordinate-Relay.Example.Test/events"], + ["e", "E0266E3CFB0D2886F91C73F5F868F3B98273713E5FCD97C081663F5518A4B3AF", "WSS://Event-Relay.Example.Test/events"], ["status", "accepted"], - ["p", "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", "WSS://Author-Relay.Example.Test/events"] + ["p", "585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF", "WSS://Author-Relay.Example.Test/events"] ] }, "expected": {"error": "non_canonical_field"} @@ -766,9 +766,9 @@ "content": "", "tags": [ ["d", "DDDDDDDDDDDDDDDDDDDDDw"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ"], ["status", "accepted"], - ["p", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"] + ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"] ] }, "expected": {"error": "author_hint_mismatch"} @@ -781,7 +781,7 @@ "content": "", "tags": [ ["d", "farm-tour-rsvp"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ"], ["status", "accepted"] ] }, @@ -796,7 +796,7 @@ "tags": [ ["d", "AAAAAAAAAAAAAAAAAAAAAA"], ["title", "Uppercase coordinate"], - ["a", "31922:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB:BBBBBBBBBBBBBBBBBBBBBQ"] + ["a", "31922:585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF:BBBBBBBBBBBBBBBBBBBBBQ"] ] }, "expected": {"error": "non_canonical_field", "field": "event_reference"} @@ -810,7 +810,7 @@ "tags": [ ["d", "AAAAAAAAAAAAAAAAAAAAAA"], ["title", "Uppercase relay"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", "WSS://Relay.Example.Test/events"] + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "WSS://Relay.Example.Test/events"] ] }, "expected": {"error": "non_canonical_field", "field": "event_reference"} @@ -823,7 +823,7 @@ "content": "", "tags": [ ["d", "DDDDDDDDDDDDDDDDDDDDDw"], - ["a", "31922:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB:BBBBBBBBBBBBBBBBBBBBBQ"], + ["a", "31922:585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF:BBBBBBBBBBBBBBBBBBBBBQ"], ["status", "accepted"] ] }, @@ -837,8 +837,8 @@ "content": "", "tags": [ ["d", "DDDDDDDDDDDDDDDDDDDDDw"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ"], - ["e", "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ"], + ["e", "E0266E3CFB0D2886F91C73F5F868F3B98273713E5FCD97C081663F5518A4B3AF"], ["status", "accepted"] ] }, @@ -852,9 +852,9 @@ "content": "", "tags": [ ["d", "DDDDDDDDDDDDDDDDDDDDDw"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ"], ["status", "accepted"], - ["p", "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"] + ["p", "585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF"] ] }, "expected": {"error": "non_canonical_field", "field": "author_hint"} @@ -867,7 +867,7 @@ "content": "", "tags": [ ["d", "DDDDDDDDDDDDDDDDDDDDDw"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", "WSS://Coordinate-Relay.Example.Test/events"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "WSS://Coordinate-Relay.Example.Test/events"], ["status", "accepted"] ] }, @@ -881,8 +881,8 @@ "content": "", "tags": [ ["d", "DDDDDDDDDDDDDDDDDDDDDw"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ"], - ["e", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "WSS://Event-Relay.Example.Test/events"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ"], + ["e", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "WSS://Event-Relay.Example.Test/events"], ["status", "accepted"] ] }, @@ -896,9 +896,9 @@ "content": "", "tags": [ ["d", "DDDDDDDDDDDDDDDDDDDDDw"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ"], ["status", "accepted"], - ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "WSS://Author-Relay.Example.Test/events"] + ["p", "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "WSS://Author-Relay.Example.Test/events"] ] }, "expected": {"error": "non_canonical_field", "field": "author_hint"} diff --git a/contracts/conformance/vectors/comment/verified_profile.v1.json b/contracts/conformance/vectors/comment/verified_profile.v1.json @@ -14560,7 +14560,7 @@ "id": "project_parent_author_mismatch", "kind": "social.comment.project_verified_event.invalid", "input": { - "event_json": "{\"id\":\"c44cc89ecf98c8cf2e596ea8bb7b99993fcd2767c0ed2842c8ca3d8281342c0a\",\"pubkey\":\"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df\",\"created_at\":1800000200,\"kind\":1111,\"tags\":[[\"E\",\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"wss://victoria.example\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"K\",\"30402\"],[\"P\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\",\"wss://victoria.example\"],[\"e\",\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"wss://victoria.example\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"k\",\"30402\"],[\"p\",\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\",\"wss://victoria.example\"]],\"content\":\"Are these carrots available Saturday?\",\"sig\":\"ca7d4eff81d73e21fbd9459733b8e4cb8ea92661b2c2b4fcc23dbf68bdd648e07243c6c78260592957b02b64044ee7e9af93a98b754b3177425e637af7592497\"}" + "event_json": "{\"id\":\"85d1e0149f8263efc02185a1bba50c3955fdee1fd7598e197b20b493f8e5a022\",\"pubkey\":\"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df\",\"created_at\":1800000200,\"kind\":1111,\"tags\":[[\"E\",\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"wss://victoria.example\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"K\",\"30402\"],[\"P\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\",\"wss://victoria.example\"],[\"e\",\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"wss://victoria.example\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"k\",\"30402\"],[\"p\",\"1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c\",\"wss://victoria.example\"]],\"content\":\"Are these carrots available Saturday?\",\"sig\":\"cb00151021c7152d8990d1d84c1781c9f9e835909c94485231363e2223220d6a480debb1abc75d6f450c4c63050966a4688740621f33cbe05cd0b181c50003ef\"}" }, "expected": { "error": "comment_parent_author_mismatch" diff --git a/contracts/conformance/vectors/deletion/verified_profile.v1.json b/contracts/conformance/vectors/deletion/verified_profile.v1.json @@ -213,8 +213,8 @@ "kind": "social.deletion_request.build_authored_draft.valid", "input": { "address_targets": [ - "31923:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd:market", - "30000:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:produce" + "31923:5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4:market", + "30000:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:produce" ], "content": "superseded", "event_targets": [ @@ -250,11 +250,11 @@ ], [ "a", - "30000:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:produce" + "30000:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:produce" ], [ "a", - "31923:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd:market" + "31923:5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4:market" ], [ "k", @@ -13117,51 +13117,51 @@ "id": "nip09_project_signed_address_replaceable_boundaries", "kind": "social.deletion_request.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"ca629e60259cd0ac499e85fe3e3c97c9a846311ad17cf9576bf00fe7dd349e5c\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":2,\"kind\":5,\"tags\":[[\"a\",\"0:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\"],[\"a\",\"3:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:\"],[\"a\",\"10000:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:\"],[\"a\",\"19999:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd:\"]],\"content\":\"\",\"sig\":\"8b29a65a47a30047eaab29ad774f6afb116be114937ea7a7aeb158cd7fc81f08dfa413386942fc4a7db0e64875c94ca4aa2f2272696c62b424649d261afafd44\"}" + "event_json": "{\"id\":\"e0ef10c9e31c32deabe3cb516f289415de0266f8cb96cd2c603f8db1ed4b0d9a\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":2,\"kind\":5,\"tags\":[[\"a\",\"0:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:\"],[\"a\",\"3:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:\"],[\"a\",\"10000:1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c:\"],[\"a\",\"19999:5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4:\"]],\"content\":\"\",\"sig\":\"1c1ab28a42f8b49daf29cfd4511d46a54a6ee32ffdab2d9bfede5fb55045140023eb4ddc57284e0cc9984f3c94167bd4f996ab74c486338d216c75c83f541c72\"}" }, "expected": { "address_targets": [ { - "coordinate": "0:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:", + "coordinate": "0:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:", "identifier": "", "kind": 0, - "pubkey": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "pubkey": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "raw_tag": [ "a", - "0:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:" + "0:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:" ], "tag_index": 0 }, { - "coordinate": "10000:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:", + "coordinate": "10000:1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c:", "identifier": "", "kind": 10000, - "pubkey": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "pubkey": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c", "raw_tag": [ "a", - "10000:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:" + "10000:1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c:" ], "tag_index": 2 }, { - "coordinate": "19999:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd:", + "coordinate": "19999:5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4:", "identifier": "", "kind": 19999, - "pubkey": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "pubkey": "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4", "raw_tag": [ "a", - "19999:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd:" + "19999:5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4:" ], "tag_index": 3 }, { - "coordinate": "3:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:", + "coordinate": "3:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:", "identifier": "", "kind": 3, - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "raw_tag": [ "a", - "3:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:" + "3:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:" ], "tag_index": 1 } @@ -13173,19 +13173,19 @@ "raw_tags": [ [ "a", - "0:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:" + "0:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:" ], [ "a", - "3:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:" + "3:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:" ], [ "a", - "10000:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:" + "10000:1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c:" ], [ "a", - "19999:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd:" + "19999:5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4:" ] ] } @@ -13194,29 +13194,29 @@ "id": "nip09_project_signed_addressable_boundaries", "kind": "social.deletion_request.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"550e49ccc8f4f479bef48605d375ba4ff5f0f8a0fcac449234ace7419b42fa99\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":3,\"kind\":5,\"tags\":[[\"a\",\"30000:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\"],[\"a\",\"39999:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm:row:7\"]],\"content\":\"\",\"sig\":\"897bb197ab6a688ecc057e57151fc24519a1fddb6f6f734821effc8d0a9d2629c13cf13797582b5572c5bc6f3a0a6d4cb96a58ffdfbf5d910deae99e32399a2d\"}" + "event_json": "{\"id\":\"1d3c5d5f0e141adbd65a871ab9ac5c742f75c70ec729631945a73c461dd01fa4\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":3,\"kind\":5,\"tags\":[[\"a\",\"30000:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:\"],[\"a\",\"39999:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:farm:row:7\"]],\"content\":\"\",\"sig\":\"ac7e31bdeab52734e8ef6913c0e23867e791c793d0e79501620a1144ba3e41216fb650c5ca23e5f0b2d4cdb40b15da525cde9bdffe09bcf7e97744178abcb651\"}" }, "expected": { "address_targets": [ { - "coordinate": "30000:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:", + "coordinate": "30000:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:", "identifier": "", "kind": 30000, - "pubkey": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "pubkey": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "raw_tag": [ "a", - "30000:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:" + "30000:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:" ], "tag_index": 0 }, { - "coordinate": "39999:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm:row:7", + "coordinate": "39999:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:farm:row:7", "identifier": "farm:row:7", "kind": 39999, - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "raw_tag": [ "a", - "39999:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm:row:7" + "39999:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:farm:row:7" ], "tag_index": 1 } @@ -13228,11 +13228,11 @@ "raw_tags": [ [ "a", - "30000:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:" + "30000:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:" ], [ "a", - "39999:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm:row:7" + "39999:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:farm:row:7" ] ] } @@ -13241,18 +13241,18 @@ "id": "nip09_project_signed_mixed_raw_retention", "kind": "social.deletion_request.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"4206395f0c18d86536bd57e6ca38cbb48dcf44ac1d0a22904190442445d2fc3f\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":4,\"kind\":5,\"tags\":[[\"x\",\"unknown\",\"retained\"],[\"e\",\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\",\"wss://relay.example\",\"root\"],[\"a\",\"30000:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:produce\",\"trailing\"],[\"k\",\"30000\",\"trailing\"]],\"content\":\"raw order\",\"sig\":\"d6078beab27d6ed5c3427a98639a081c255d2faed7efd89207f1839b40f5b06c1584f91224a9a3e13360861923488f89147091c130c701cb3053ec27e1a0d7dc\"}" + "event_json": "{\"id\":\"f50b6892d049f34e941eb691ef4a4b956217a44ca68f3aa0c4ef7e0ca360d092\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":4,\"kind\":5,\"tags\":[[\"x\",\"unknown\",\"retained\"],[\"e\",\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\",\"wss://relay.example\",\"root\"],[\"a\",\"30000:1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c:produce\",\"trailing\"],[\"k\",\"30000\",\"trailing\"]],\"content\":\"raw order\",\"sig\":\"df09f81f6b6ca7e4c18aee1a9476ed56b6fbe5acba2ce7be73f6a617db7db9a522691f64034377902cfd0f36750992fd2984c1c334f49a2f49ba3d2a7c0a66a7\"}" }, "expected": { "address_targets": [ { - "coordinate": "30000:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:produce", + "coordinate": "30000:1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c:produce", "identifier": "produce", "kind": 30000, - "pubkey": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "pubkey": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c", "raw_tag": [ "a", - "30000:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:produce", + "30000:1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c:produce", "trailing" ], "tag_index": 2 @@ -13297,7 +13297,7 @@ ], [ "a", - "30000:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:produce", + "30000:1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c:produce", "trailing" ], [ @@ -13312,18 +13312,18 @@ "id": "nip09_project_signed_duplicate_targets_first_provenance", "kind": "social.deletion_request.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"ef7b4f50235a637d9859d7f5ad879bc1e423a59da6835e82cbcd7c368c733b26\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":5,\"kind\":5,\"tags\":[[\"e\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\",\"first\"],[\"e\",\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"second\"],[\"a\",\"030000:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB:produce\",\"first\"],[\"a\",\"30000:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:produce\",\"second\"]],\"content\":\"\",\"sig\":\"dded0dcec9cebf45c443ec736ccf096911cf57adfd45b2b3143c60e26c95582167c05bbce452b0adcbf333fe4471c0c95d58fc466a87e6349820301d738047b3\"}" + "event_json": "{\"id\":\"b922ee8c829b7caf95227a5b290511f81a7f7c56b98af57673adfd5bbf8b4834\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":5,\"kind\":5,\"tags\":[[\"e\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\",\"first\"],[\"e\",\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"second\"],[\"a\",\"030000:E0266E3CFB0D2886F91C73F5F868F3B98273713E5FCD97C081663F5518A4B3AF:produce\",\"first\"],[\"a\",\"30000:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:produce\",\"second\"]],\"content\":\"\",\"sig\":\"c945d8be7013cc8db307a70d271977fedfbc479416f457baf08b18a4e9e64923420af6156bf44e84e6c466e71ecd4c1baf529384067fd8d2f82d4fc0802a1534\"}" }, "expected": { "address_targets": [ { - "coordinate": "30000:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:produce", + "coordinate": "30000:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:produce", "identifier": "produce", "kind": 30000, - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "raw_tag": [ "a", - "030000:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB:produce", + "030000:E0266E3CFB0D2886F91C73F5F868F3B98273713E5FCD97C081663F5518A4B3AF:produce", "first" ], "tag_index": 2 @@ -13356,12 +13356,12 @@ ], [ "a", - "030000:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB:produce", + "030000:E0266E3CFB0D2886F91C73F5F868F3B98273713E5FCD97C081663F5518A4B3AF:produce", "first" ], [ "a", - "30000:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:produce", + "30000:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:produce", "second" ] ] @@ -13371,29 +13371,29 @@ "id": "nip09_project_signed_canonical_effect_sorting", "kind": "social.deletion_request.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"682de0df23f548c7e1e8272ff7776c5574ea12b18041e46004f6045263433a27\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":6,\"kind\":5,\"tags\":[[\"e\",\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\"],[\"a\",\"31923:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd:market\"],[\"e\",\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"],[\"a\",\"30000:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:produce\"]],\"content\":\"\",\"sig\":\"9d6a1bc42f42739042c0bef26ff5557176f571b152cd30b730b3a2ea388a874827f7ecf1ed4241234fe50143da77640542ecd5af4263900981760d1be616eea2\"}" + "event_json": "{\"id\":\"c85bb88aff6fe36198851dbc8638ad8b288a861d18d4834ed61e3545cde97a09\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":6,\"kind\":5,\"tags\":[[\"e\",\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\"],[\"a\",\"31923:5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4:market\"],[\"e\",\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"],[\"a\",\"30000:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:produce\"]],\"content\":\"\",\"sig\":\"1f15aeb3016d5533c675d227b79d59f59e77c78cbbe4d59ec25a2d7624c8836c162990e1b388c6c0ee6800e18f512b0216a2ade79788d1b032c0f74278558f3a\"}" }, "expected": { "address_targets": [ { - "coordinate": "30000:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:produce", + "coordinate": "30000:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:produce", "identifier": "produce", "kind": 30000, - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "raw_tag": [ "a", - "30000:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:produce" + "30000:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:produce" ], "tag_index": 3 }, { - "coordinate": "31923:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd:market", + "coordinate": "31923:5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4:market", "identifier": "market", "kind": 31923, - "pubkey": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "pubkey": "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4", "raw_tag": [ "a", - "31923:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd:market" + "31923:5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4:market" ], "tag_index": 1 } @@ -13426,7 +13426,7 @@ ], [ "a", - "31923:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd:market" + "31923:5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4:market" ], [ "e", @@ -13434,7 +13434,7 @@ ], [ "a", - "30000:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:produce" + "30000:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:produce" ] ] } @@ -13443,18 +13443,18 @@ "id": "nip09_project_signed_kind_advisory_diagnostics", "kind": "social.deletion_request.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"e8c11c5d1fd81bee0423a6f20db42786cc36f4c8922845c22ad0753bc4d10447\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":7,\"kind\":5,\"tags\":[[\"a\",\"30000:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:produce\"],[\"k\",\"30000\"],[\"k\"],[\"k\",\"030000\"],[\"k\",\"30000\",\"duplicate\"],[\"k\",\"5\"]],\"content\":\"\",\"sig\":\"3c7b7ad36ef173e61d85cd22989e5694e8373c670bf3b84dabf602c4dc17313eba107952969ac92521900e7f10a1fce80a6f90120e09705740a3dc5b4491c1a9\"}" + "event_json": "{\"id\":\"a7759259b243f84005168ed7a11c626d1156c99393e51610c54f511ece3ea516\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":7,\"kind\":5,\"tags\":[[\"a\",\"30000:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:produce\"],[\"k\",\"30000\"],[\"k\"],[\"k\",\"030000\"],[\"k\",\"30000\",\"duplicate\"],[\"k\",\"5\"]],\"content\":\"\",\"sig\":\"6205f197be2f061e31950234b4ad3a9b90659710a2d65836f8d243517fc4e1aac2f3d54f4eab401dba81d6481be687a2a0df9c482e6cc575ace1e5b3f405a065\"}" }, "expected": { "address_targets": [ { - "coordinate": "30000:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:produce", + "coordinate": "30000:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:produce", "identifier": "produce", "kind": 30000, - "pubkey": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "pubkey": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "raw_tag": [ "a", - "30000:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:produce" + "30000:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:produce" ], "tag_index": 0 } @@ -13516,7 +13516,7 @@ "raw_tags": [ [ "a", - "30000:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:produce" + "30000:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:produce" ], [ "k", @@ -23395,7 +23395,7 @@ "id": "nip09_project_signed_address_target_unsupported_kind", "kind": "social.deletion_request.project_verified_event.invalid", "input": { - "event_json": "{\"id\":\"9489e523cdf3103b1608cd03a4c31f8c2f83fa8b092521cac782ee8ff7e006ad\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":33,\"kind\":5,\"tags\":[[\"a\",\"20000:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\"]],\"content\":\"\",\"sig\":\"b3479000500fd8453232d995e1c36073ce20f0ef579ddcc6122c9dd23525b37d726fe1f0a98e036a208726876a737dfb6fdc21acb10e28cf59ed80962b2a0ad2\"}" + "event_json": "{\"id\":\"5c6e3d68c69fa58615cb7db74edaabf055390101947bcced291ba00edd8b2a7d\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":33,\"kind\":5,\"tags\":[[\"a\",\"20000:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:\"]],\"content\":\"\",\"sig\":\"df67f12a606578fd9da58fe2e2edf1964844d816afc08d34b625d976dc536a6d218953c38f8151265ca6f4f4cdac6a973fba40c4925e27756a54d072379adea8\"}" }, "expected": { "error": "deletion_address_target_invalid" @@ -23405,7 +23405,7 @@ "id": "nip09_project_signed_address_target_identifier_forbidden", "kind": "social.deletion_request.project_verified_event.invalid", "input": { - "event_json": "{\"id\":\"cb5e015b280e5a5cdce1aab86ca69ff0b5ab02463e59e385aa2423b91850c374\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":34,\"kind\":5,\"tags\":[[\"a\",\"10000:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:forbidden\"]],\"content\":\"\",\"sig\":\"689d9788b632d8400d9f29a460b94402ff0dac7ef5a1df971235ce32fe91f758ecee66dfee6c208b6eef6d3dff6d42c874e7b6ea10d1a8a7ecc5cc4fdf167985\"}" + "event_json": "{\"id\":\"d3dabd8d980b0303eaf0384984ae3e30fcd4a3d4780d4bc03645427fab3ec48a\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":34,\"kind\":5,\"tags\":[[\"a\",\"10000:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:forbidden\"]],\"content\":\"\",\"sig\":\"afd5a1c45d68e29c1747d608d4ced1afbe9c3079a4df2696184a9a354a2b360a8881eb35764a17d2cbe66fe69a107237058936bf5259d7e4fa0197d48cc9eef7\"}" }, "expected": { "error": "deletion_address_target_invalid" @@ -23554,18 +23554,18 @@ "id": "nip09_admit_signed_address_target", "kind": "social.deletion_request.verify_and_admit_event.valid", "input": { - "event_json": "{\"id\":\"ca06409e5b9f6020a4ddd64c01cddb21a60bc0c878aae16e4e86ec862db0259a\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":51,\"kind\":5,\"tags\":[[\"a\",\"30000:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:produce\"]],\"content\":\"\",\"sig\":\"3a9d2b64027f54aa7c4cf7a71f59f46626c7f7da328c14f15df0e1e20c135d6c39249ecd87ae2a52cd09fa6248b2124c1dde1b7c0c7a79cec859d1314a4ae050\"}" + "event_json": "{\"id\":\"1db5e2667b7de3f36f5bdff85ca82d5edfb76936bcdf3a15042b94866f835117\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":51,\"kind\":5,\"tags\":[[\"a\",\"30000:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:produce\"]],\"content\":\"\",\"sig\":\"5cec31910d443b971d276589b8770dfe6692f9e5dc7169a9359d4222c1ecb9cbc3366bc649388d5bef6ac92f84ed5e46025013143fd1b5457d465e5b94d2d24e\"}" }, "expected": { "address_targets": [ { - "coordinate": "30000:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:produce", + "coordinate": "30000:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:produce", "identifier": "produce", "kind": 30000, - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "raw_tag": [ "a", - "30000:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:produce" + "30000:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:produce" ], "tag_index": 0 } @@ -23577,7 +23577,7 @@ "raw_tags": [ [ "a", - "30000:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:produce" + "30000:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:produce" ] ] } @@ -23586,18 +23586,18 @@ "id": "nip09_admit_signed_mixed_tolerant_projection", "kind": "social.deletion_request.verify_and_admit_event.valid", "input": { - "event_json": "{\"id\":\"be56e90b66e7e2c8bbd72d97e940f28a9da0549e3ff3ea9fb76246f08f8054e2\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":52,\"kind\":5,\"tags\":[[\"x\",\"retained\"],[\"e\",\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\",\"relay\"],[\"a\",\"31923:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:market\",\"extra\"],[\"k\",\"31923\"]],\"content\":\"withdrawn\",\"sig\":\"24b858e8f25c939112a4f69a9d5e5c53e7deeffcefe3311adacb2ad6ff1ad4df7c247f5e92d90efb1d023dcc3d733f3e71f63c3d66e10464db1b8e2156663c92\"}" + "event_json": "{\"id\":\"114bc1c32e196912dbe03352046f1718e0e66363711ec4c3491891b04080108a\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":52,\"kind\":5,\"tags\":[[\"x\",\"retained\"],[\"e\",\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\",\"relay\"],[\"a\",\"31923:1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c:market\",\"extra\"],[\"k\",\"31923\"]],\"content\":\"withdrawn\",\"sig\":\"8e0ee72c28606705747eae21f0cbb546ea22946b160c46353b673e07004093aea29650be9cd4d12d34111a8f0efac9b7140f7d3f3f9a46c5ec9b7a00887b89c8\"}" }, "expected": { "address_targets": [ { - "coordinate": "31923:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:market", + "coordinate": "31923:1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c:market", "identifier": "market", "kind": 31923, - "pubkey": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "pubkey": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c", "raw_tag": [ "a", - "31923:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:market", + "31923:1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c:market", "extra" ], "tag_index": 2 @@ -23638,7 +23638,7 @@ ], [ "a", - "31923:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:market", + "31923:1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c:market", "extra" ], [ diff --git a/contracts/conformance/vectors/post/verified_profiles.v1.json b/contracts/conformance/vectors/post/verified_profiles.v1.json @@ -143,7 +143,7 @@ "content": "Direct reply", "root": { "event_id": "1111111111111111111111111111111111111111111111111111111111111111", - "author": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "author": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": "wss://root.relay.example" } }, @@ -152,7 +152,7 @@ "content": "Direct reply", "tags": [ ["e", "1111111111111111111111111111111111111111111111111111111111111111", "wss://root.relay.example", "root"], - ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"] + ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"] ] } }, @@ -163,12 +163,12 @@ "content": "Nested reply", "root": { "event_id": "1111111111111111111111111111111111111111111111111111111111111111", - "author": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "author": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null }, "parent": { "event_id": "2222222222222222222222222222222222222222222222222222222222222222", - "author": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "author": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c", "relay": "wss://parent.relay.example" } }, @@ -178,8 +178,8 @@ "tags": [ ["e", "1111111111111111111111111111111111111111111111111111111111111111", "", "root"], ["e", "2222222222222222222222222222222222222222222222222222222222222222", "wss://parent.relay.example", "reply"], - ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - ["p", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"] + ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], + ["p", "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c"] ] } }, @@ -190,12 +190,12 @@ "content": "Ambiguous", "root": { "event_id": "1111111111111111111111111111111111111111111111111111111111111111", - "author": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "author": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null }, "parent": { "event_id": "1111111111111111111111111111111111111111111111111111111111111111", - "author": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "author": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c", "relay": null } }, @@ -210,7 +210,7 @@ "content": "Invalid", "root": { "event_id": "not-an-event-id", - "author": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "author": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null } }, @@ -225,7 +225,7 @@ "content": "Canonical relay", "root": { "event_id": "1111111111111111111111111111111111111111111111111111111111111111", - "author": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "author": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": "wss://[2001:db8::1]:8443/nostr?region=ca-bc&next=%2Ffeed" } }, @@ -234,7 +234,7 @@ "content": "Canonical relay", "tags": [ ["e", "1111111111111111111111111111111111111111111111111111111111111111", "wss://[2001:db8::1]:8443/nostr?region=ca-bc&next=%2Ffeed", "root"], - ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"] + ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"] ] } }, @@ -245,7 +245,7 @@ "content": "Invalid relay", "root": { "event_id": "1111111111111111111111111111111111111111111111111111111111111111", - "author": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "author": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": "wss://%" } }, @@ -260,7 +260,7 @@ "content": "Invalid relay", "root": { "event_id": "1111111111111111111111111111111111111111111111111111111111111111", - "author": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "author": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": "wss://%zz" } }, @@ -275,7 +275,7 @@ "content": "Invalid relay", "root": { "event_id": "1111111111111111111111111111111111111111111111111111111111111111", - "author": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "author": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": "wss://256.1.1.1" } }, @@ -290,7 +290,7 @@ "content": "Invalid relay", "root": { "event_id": "1111111111111111111111111111111111111111111111111111111111111111", - "author": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "author": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": "wss://[v1.foo]" } }, @@ -305,7 +305,7 @@ "content": "Invalid relay", "root": { "event_id": "1111111111111111111111111111111111111111111111111111111111111111", - "author": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "author": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": "wss://relay.example:" } }, @@ -320,7 +320,7 @@ "content": "Invalid relay", "root": { "event_id": "1111111111111111111111111111111111111111111111111111111111111111", - "author": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "author": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": "wss://relay.example:0" } }, @@ -335,7 +335,7 @@ "content": "Invalid relay", "root": { "event_id": "1111111111111111111111111111111111111111111111111111111111111111", - "author": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "author": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": "wss://relay.example:65536" } }, @@ -347,7 +347,7 @@ "id": "project_signed_nip10_marked_direct", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"2340fc3fec291f4d4429bf13bf23cc3b7ec8589aa5e6426a5fc5a25bfcf1a896\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000001,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"Direct reply\",\"sig\":\"16afb66cf2e30450a1055d697044b0f27835352553f32f7ac8d18387cc27861dfde3bb820a8882c00f933c13d4c967df5d5db986cc228a80dd3d291841bf08cd\"}" + "event_json": "{\"id\":\"d62b9340ac9808fc84a751788d017344ede91aea1c89081be3f7bff4a2266354\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000001,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"Direct reply\",\"sig\":\"206758bee31328a53457e3190b046a4a184941223f4e8ed1696db28d71c9af03138fe9add32d5e97d6f3b50bd0f78e4d5a91629dbf4d12aedd4315ce96c97e8c\"}" }, "expected": { "style": "marked", @@ -365,8 +365,8 @@ "participants": [ { "tag_index": 1, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null } ], @@ -377,7 +377,7 @@ "id": "project_signed_nip10_marked_with_citation", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"b6bd8c4e2c8e3098a0b6fdbefbf7a25285887519e2ea58738af4221ddb5fd39e\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000016,\"kind\":1,\"tags\":[[\"e\",\"3333333333333333333333333333333333333333333333333333333333333333\",\"wss://relay.example\",\"\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"],[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"Marked reply with citation\",\"sig\":\"9f6516def04521e4e9c9b27f1225e43c03919914c8ced58dfb0afd5ee4fb950bcbbe42ba505f00f75be399ac4a61f7a7eb612b58051bc78ae245b7b122f760e4\"}" + "event_json": "{\"id\":\"5e6db69a9c9968a8f1eb3699ddcf19c0e7b7c9255df616ce7032928b93ad0f6a\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000016,\"kind\":1,\"tags\":[[\"e\",\"3333333333333333333333333333333333333333333333333333333333333333\",\"wss://relay.example\",\"\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"Marked reply with citation\",\"sig\":\"d610d090bab46e06d4a674d4bdfd3204f64bc8d1b94929d64cd9ddfd604de89dc9c5ac87229e2f095091e7cac2805ef2ad45325b019e2a79c89b677981f3b068\"}" }, "expected": { "style": "marked", @@ -394,17 +394,17 @@ "citations": [ { "tag_index": 0, - "raw_tag": ["e", "3333333333333333333333333333333333333333333333333333333333333333", "wss://relay.example", "", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], + "raw_tag": ["e", "3333333333333333333333333333333333333333333333333333333333333333", "wss://relay.example", "", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], "event_id": "3333333333333333333333333333333333333333333333333333333333333333", "relay": "wss://relay.example", - "author_hint": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + "author_hint": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af" } ], "participants": [ { "tag_index": 2, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null } ], @@ -415,7 +415,7 @@ "id": "project_signed_nip10_marked_with_malformed_citation", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"c346aaff3f00a5c8fac4d8dcc15f286f56acbc4608c2e67e799266643f2544fa\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000017,\"kind\":1,\"tags\":[[\"e\",\"3333333333333333333333333333333333333333333333333333333333333333\",\"\",\"mention\"],[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"Marked reply with malformed citation\",\"sig\":\"25d8248ba0220435036611dfbf14c4d52f63a2f29e568f9fd79435faa126d7f862068a1db66dac9a2179911e084eb12a03948a51f0ad7a50ab4fc6a83491037b\"}" + "event_json": "{\"id\":\"19a98ea4c777451618f4f36549abbc352f55c27e254978a2a0dcc0c910cc52ce\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000017,\"kind\":1,\"tags\":[[\"e\",\"3333333333333333333333333333333333333333333333333333333333333333\",\"\",\"mention\"],[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"Marked reply with malformed citation\",\"sig\":\"8fbb467df2771e7a6fc67ca12bfefa2e5b635bfe16d8b963df29d7d8a8df3387e7f9229677045317e470247656db8c87261dc1cf38580c1856b32b2a4fb5791c\"}" }, "expected": { "style": "marked", @@ -433,8 +433,8 @@ "participants": [ { "tag_index": 2, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null } ], @@ -451,7 +451,7 @@ "id": "project_signed_nip10_marked_nested_reordered", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"8179bf853f4b24f4ba7af58f162c0dabf08e74c2fe27df4e5573e48d86a8c1c5\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000002,\"kind\":1,\"tags\":[[\"e\",\"2222222222222222222222222222222222222222222222222222222222222222\",\"wss://parent.relay.example\",\"reply\",\"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\"],[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"wss://root.relay.example\",\"root\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"],[\"p\",\"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"Nested reply\",\"sig\":\"53b88d556d28f98b43ee36eb8b6453d1fa36da7058891100608ab8e0842dc3d1c49de29323f08679ecbee9e49cf3a09c59139c9e7285826dc7db479dd6219fd3\"}" + "event_json": "{\"id\":\"be4126cc38031f6d47a3d00c81d281999fb4dc6e73ae4bf4b757271be5b0abc0\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000002,\"kind\":1,\"tags\":[[\"e\",\"2222222222222222222222222222222222222222222222222222222222222222\",\"wss://parent.relay.example\",\"reply\",\"1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c\"],[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"wss://root.relay.example\",\"root\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"p\",\"1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"Nested reply\",\"sig\":\"4e8439d145b4ce2366818fa6f0722e23bf664c92dbf10728fbad3c223d38150ef160566854e052172ff8c060f8924d030bd24c32919967b6f131771c1376e590\"}" }, "expected": { "style": "marked", @@ -459,30 +459,30 @@ "direct": false, "root": { "tag_index": 1, - "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "wss://root.relay.example", "root", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], + "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "wss://root.relay.example", "root", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], "event_id": "1111111111111111111111111111111111111111111111111111111111111111", "relay": "wss://root.relay.example", - "author_hint": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + "author_hint": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af" }, "parent": { "tag_index": 0, - "raw_tag": ["e", "2222222222222222222222222222222222222222222222222222222222222222", "wss://parent.relay.example", "reply", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"], + "raw_tag": ["e", "2222222222222222222222222222222222222222222222222222222222222222", "wss://parent.relay.example", "reply", "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c"], "event_id": "2222222222222222222222222222222222222222222222222222222222222222", "relay": "wss://parent.relay.example", - "author_hint": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + "author_hint": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c" }, "citations": [], "participants": [ { "tag_index": 2, - "raw_tag": ["p", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"], - "pubkey": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "raw_tag": ["p", "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c"], + "pubkey": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c", "relay": null }, { "tag_index": 3, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null } ], @@ -493,7 +493,7 @@ "id": "project_signed_nip10_positional_direct", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"802da76963580d5932a400a2e56e73caccb80c78d43845c62f5fd95feee600e8\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000003,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"Legacy direct reply\",\"sig\":\"9a1a958170b2faf3c467bf174e776f7f61bf886644657cc12d92d6a9782db89f273508e1d940412645bbb73a6ce7948b7d20daa77647aa5fd8f9e164159826e7\"}" + "event_json": "{\"id\":\"a7141da919755d6ace9b5fa400928d512b4ef785c0ec03d55989bc2d6cbce860\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000003,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"Legacy direct reply\",\"sig\":\"eb2112223ed35f4b0919578a4981e08b403779391f6f9a831ea51763779028d85f72ce8224b1ae469ad6baea21d1d275210bb438a126b4391dab0c347051917a\"}" }, "expected": { "style": "legacy_positional", @@ -511,8 +511,8 @@ "participants": [ { "tag_index": 1, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null } ], @@ -523,7 +523,7 @@ "id": "project_signed_nip10_positional_many", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"71af1b702a370218eeb1d6d4fd4734c8cd5fbc64c02ef90196365bda0755490b\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000004,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"wss://root.relay.example\"],[\"e\",\"3333333333333333333333333333333333333333333333333333333333333333\"],[\"e\",\"2222222222222222222222222222222222222222222222222222222222222222\",\"wss://parent.relay.example\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"],[\"p\",\"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\"]],\"content\":\"Legacy nested reply\",\"sig\":\"49d2bf6c65edab401f7d981bf7bd87b7b1ece61d347f75270f38cf67597791f4058c6bd58444a52f831b0cd15c1f91e18958b3ca877a196ababd7055247d65aa\"}" + "event_json": "{\"id\":\"d3f1220f5cb9d51a76cf2551d27cbbb7cfbb5f68ad221045118eb1fd313c9d64\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000004,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"wss://root.relay.example\"],[\"e\",\"3333333333333333333333333333333333333333333333333333333333333333\"],[\"e\",\"2222222222222222222222222222222222222222222222222222222222222222\",\"wss://parent.relay.example\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"p\",\"1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c\"]],\"content\":\"Legacy nested reply\",\"sig\":\"41a3c1da0c331dc67b1a79eb440dee86b1e6baf11f54fd8e1771ebacb0c0681500d5eece1933fa3c68ca745d552a97753378acac06ce5a7328da0086387f5c59\"}" }, "expected": { "style": "legacy_positional", @@ -555,14 +555,14 @@ "participants": [ { "tag_index": 3, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null }, { "tag_index": 4, - "raw_tag": ["p", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"], - "pubkey": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "raw_tag": ["p", "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c"], + "pubkey": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c", "relay": null } ], @@ -573,7 +573,7 @@ "id": "project_signed_nip10_positional_direct_with_author_hint", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"ff050a31d73546d609080281ad2c1e98f878aba826108e7ee0462cf6b397a941\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000018,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"wss://root.relay.example\",\"\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"Legacy direct with author hint\",\"sig\":\"e71bcb61d49862cd7fa1c776e4fe51aa9e4198234ee93efeacc9afc3d7038c00dee246f1df19eb0fd22aee0a70436708faec39e92bee16e86601f1c91fee1117\"}" + "event_json": "{\"id\":\"f885bad6dc41077036097e81bedb19a0b6b78a48cee24513eb788a997353802c\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000018,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"wss://root.relay.example\",\"\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"Legacy direct with author hint\",\"sig\":\"473111ec136bcf38035a1848c6fa02ac2ba2a946c3270485d93c11287a3ebb0ac87e6a90b1b91d8beb4f8f958a2b58a3cf494622eafad8fb91cb1fdf5f64bcd0\"}" }, "expected": { "style": "legacy_positional", @@ -581,18 +581,18 @@ "direct": true, "root": { "tag_index": 0, - "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "wss://root.relay.example", "", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], + "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "wss://root.relay.example", "", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], "event_id": "1111111111111111111111111111111111111111111111111111111111111111", "relay": "wss://root.relay.example", - "author_hint": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + "author_hint": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af" }, "parent": null, "citations": [], "participants": [ { "tag_index": 1, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null } ], @@ -603,7 +603,7 @@ "id": "project_signed_nip10_positional_many_with_author_hints", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"2473084e4272dc675f34e18b9b2aaa3a164e3132bf19056c734759c922acafa7\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000019,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"wss://root.relay.example\",\"\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"],[\"e\",\"3333333333333333333333333333333333333333333333333333333333333333\",\"wss://citation.relay.example\",\"\",\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\"],[\"e\",\"2222222222222222222222222222222222222222222222222222222222222222\",\"wss://parent.relay.example\",\"\",\"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"],[\"p\",\"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\"],[\"p\",\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\"]],\"content\":\"Legacy nested with author hints\",\"sig\":\"e94c18ae8d2c8785a32f42dfff57712508018e2820d24497fbafcfcecc50890d19a4c15d48b2729c4f9dbe73e4c985e055097174b4505ed3a68858d4d56f7809\"}" + "event_json": "{\"id\":\"1f8d3d805ead850160ed74b446aadca7f5f44591484e1cdb22b471e5d689ece3\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000019,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"wss://root.relay.example\",\"\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"e\",\"3333333333333333333333333333333333333333333333333333333333333333\",\"wss://citation.relay.example\",\"\",\"5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4\"],[\"e\",\"2222222222222222222222222222222222222222222222222222222222222222\",\"wss://parent.relay.example\",\"\",\"1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"p\",\"1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c\"],[\"p\",\"5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4\"]],\"content\":\"Legacy nested with author hints\",\"sig\":\"6c927cc43a95f998ae43956c8e6bc0ab7c18e70dd91eef66ed8360dead902a83c921134e826100b13ea04122ca4bcdf3b0250b0852307141f0a0ed193e87fd9f\"}" }, "expected": { "style": "legacy_positional", @@ -611,44 +611,44 @@ "direct": false, "root": { "tag_index": 0, - "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "wss://root.relay.example", "", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], + "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "wss://root.relay.example", "", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], "event_id": "1111111111111111111111111111111111111111111111111111111111111111", "relay": "wss://root.relay.example", - "author_hint": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + "author_hint": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af" }, "parent": { "tag_index": 2, - "raw_tag": ["e", "2222222222222222222222222222222222222222222222222222222222222222", "wss://parent.relay.example", "", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"], + "raw_tag": ["e", "2222222222222222222222222222222222222222222222222222222222222222", "wss://parent.relay.example", "", "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c"], "event_id": "2222222222222222222222222222222222222222222222222222222222222222", "relay": "wss://parent.relay.example", - "author_hint": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + "author_hint": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c" }, "citations": [ { "tag_index": 1, - "raw_tag": ["e", "3333333333333333333333333333333333333333333333333333333333333333", "wss://citation.relay.example", "", "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"], + "raw_tag": ["e", "3333333333333333333333333333333333333333333333333333333333333333", "wss://citation.relay.example", "", "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4"], "event_id": "3333333333333333333333333333333333333333333333333333333333333333", "relay": "wss://citation.relay.example", - "author_hint": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd" + "author_hint": "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4" } ], "participants": [ { "tag_index": 3, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null }, { "tag_index": 4, - "raw_tag": ["p", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"], - "pubkey": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "raw_tag": ["p", "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c"], + "pubkey": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c", "relay": null }, { "tag_index": 5, - "raw_tag": ["p", "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"], - "pubkey": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "raw_tag": ["p", "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4"], + "pubkey": "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4", "relay": null } ], @@ -659,7 +659,7 @@ "id": "project_signed_nip10_positional_malformed_middle_citation", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"ce7684655dafc04bcb8048f4ba95da4b4780316ce90143c332ca4ed40af60ac7\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000020,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\"],[\"e\",\"3333333333333333333333333333333333333333333333333333333333333333\",\"\",\"mention\"],[\"e\",\"2222222222222222222222222222222222222222222222222222222222222222\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"],[\"p\",\"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\"]],\"content\":\"Legacy nested with malformed citation\",\"sig\":\"a278e44d6c44fe196c3557d01a99ec3cf3eaa31e16b66370743183db671eac6da75f11151b9da194582b03f529c4e9f871cf743d58dea430d0d12c3ed90c4997\"}" + "event_json": "{\"id\":\"6ea3acdf3d4df0e0dc107a514c1801f658ff44345d1c300ab12f553aaeddb40e\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000020,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\"],[\"e\",\"3333333333333333333333333333333333333333333333333333333333333333\",\"\",\"mention\"],[\"e\",\"2222222222222222222222222222222222222222222222222222222222222222\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"p\",\"1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c\"]],\"content\":\"Legacy nested with malformed citation\",\"sig\":\"261e5b2c9632cab25a308b86011655a82dbcda58c4b1908fe8f6465eebf9f250c00086927d9ddf93b73d24467c6e18774bc1b1ffe08a47342b287d86cd2a2b15\"}" }, "expected": { "style": "legacy_positional", @@ -683,14 +683,14 @@ "participants": [ { "tag_index": 3, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null }, { "tag_index": 4, - "raw_tag": ["p", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"], - "pubkey": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "raw_tag": ["p", "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c"], + "pubkey": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c", "relay": null } ], @@ -707,7 +707,7 @@ "id": "project_signed_nip10_precedes_ask_and_media", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"7911ed2e9e2e08173a357f5f83fcdc415ca0c87e95682bad28cefe3a616f5be3\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000005,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"],[\"t\",\"radroots-ask\"],[\"imeta\",\"url https://media.example/image.webp\",\"x malformed\"]],\"content\":\"Reply with compatibility metadata\",\"sig\":\"9bd6c5f40c8587893b3460a53931c1253b2764c44922b25ffb64fe3e96e7fe2b8d139d5fca5ffd7b6f5a1cf19598c2a34e7ab48f5d15b18e695a5e39c81fc9f4\"}" + "event_json": "{\"id\":\"cc9440768dea0bf58b002ace8c836893ac6c7a522bdf25048fa34a6a55c03a4a\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000005,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"t\",\"radroots-ask\"],[\"imeta\",\"url https://media.example/image.webp\",\"x malformed\"]],\"content\":\"Reply with compatibility metadata\",\"sig\":\"e28dd20ed2d04aac40f67a8cccdd6d8cb261fa54c04c1ea57d021d4d4ab9a3c48ca5e52c5c182f4204302315ee9903f39c90117558457a84daeef2505f240294\"}" }, "expected": { "style": "marked", @@ -725,8 +725,8 @@ "participants": [ { "tag_index": 1, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null } ], @@ -737,7 +737,7 @@ "id": "project_signed_nip10_invalid_relay", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"15e0f001e760eb1ac3fd15b8a85e43a5c07603d4ceccdc6ccb93e6cc1876a626\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000006,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"https://relay.example\",\"root\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"Invalid relay\",\"sig\":\"18065b4433c33b29a06ecec64f0f863482479aec2832fcde3c95d2814b5ed91310fdd44df507f346e0231206be239ed4ac85353fc60a838435ae10feae2cc7c6\"}" + "event_json": "{\"id\":\"85b05a80dd168098ea8dcdc6dfa656bcca902120f82bf36a5a5b94c1c949e122\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000006,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"https://relay.example\",\"root\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"Invalid relay\",\"sig\":\"de303499d4cee838d854be0001e686529eda96d37a7f9886f469bf49ad2269aea4b4d3671a1ca820996ba597eece5915d42fdf98452d19bcc630312b0b63f56e\"}" }, "expected": { "style": "marked", @@ -755,8 +755,8 @@ "participants": [ { "tag_index": 1, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null } ], @@ -773,7 +773,7 @@ "id": "project_signed_nip10_canonical_relay_authorities", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"a9f7683ed2eaf63e64af15dddf726ea32ec86e6079cd1038edf379c2de96a199\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000020,\"kind\":1,\"tags\":[[\"e\",\"3333333333333333333333333333333333333333333333333333333333333333\",\"wss://relay.example/nostr/v1?region=ca-bc&next=%2Ffeed\",\"\",\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\"],[\"e\",\"2222222222222222222222222222222222222222222222222222222222222222\",\"ws://127.0.0.1:21003\",\"reply\",\"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\"],[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"wss://[2001:db8::1]:8443/nostr\",\"root\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"ws://localhost:21003\"],[\"p\",\"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\",\"wss://participant.relay.example?region=ca-bc\"],[\"p\",\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\"]],\"content\":\"Canonical relay authorities\",\"sig\":\"4b1691d3d3abcb62a70041da50a0c9790871454a2fb234bac6061a97b4407f91299e905210792c1005883a800d31a7580a218172b4c8ac2834e2c6bcf5b0d925\"}" + "event_json": "{\"id\":\"e7166651c6bd2fd462f7820fca73690049ee9a589eaf161495b38c9b5fe34f92\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000020,\"kind\":1,\"tags\":[[\"e\",\"3333333333333333333333333333333333333333333333333333333333333333\",\"wss://relay.example/nostr/v1?region=ca-bc&next=%2Ffeed\",\"\",\"5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4\"],[\"e\",\"2222222222222222222222222222222222222222222222222222222222222222\",\"ws://127.0.0.1:21003\",\"reply\",\"1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c\"],[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"wss://[2001:db8::1]:8443/nostr\",\"root\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\",\"ws://localhost:21003\"],[\"p\",\"1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c\",\"wss://participant.relay.example?region=ca-bc\"],[\"p\",\"5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4\"]],\"content\":\"Canonical relay authorities\",\"sig\":\"b0faf3e55b6309077108e9e97425d5ea850cbcf5f8b73ad1bbf85731c549ab482dc7dca2cfd7f89a3e1ddd0f1ae8d243e07523ac5251310b0c685cfe0134d073\"}" }, "expected": { "style": "marked", @@ -781,44 +781,44 @@ "direct": false, "root": { "tag_index": 2, - "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "wss://[2001:db8::1]:8443/nostr", "root", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], + "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "wss://[2001:db8::1]:8443/nostr", "root", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], "event_id": "1111111111111111111111111111111111111111111111111111111111111111", "relay": "wss://[2001:db8::1]:8443/nostr", - "author_hint": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + "author_hint": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af" }, "parent": { "tag_index": 1, - "raw_tag": ["e", "2222222222222222222222222222222222222222222222222222222222222222", "ws://127.0.0.1:21003", "reply", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"], + "raw_tag": ["e", "2222222222222222222222222222222222222222222222222222222222222222", "ws://127.0.0.1:21003", "reply", "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c"], "event_id": "2222222222222222222222222222222222222222222222222222222222222222", "relay": "ws://127.0.0.1:21003", - "author_hint": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + "author_hint": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c" }, "citations": [ { "tag_index": 0, - "raw_tag": ["e", "3333333333333333333333333333333333333333333333333333333333333333", "wss://relay.example/nostr/v1?region=ca-bc&next=%2Ffeed", "", "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"], + "raw_tag": ["e", "3333333333333333333333333333333333333333333333333333333333333333", "wss://relay.example/nostr/v1?region=ca-bc&next=%2Ffeed", "", "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4"], "event_id": "3333333333333333333333333333333333333333333333333333333333333333", "relay": "wss://relay.example/nostr/v1?region=ca-bc&next=%2Ffeed", - "author_hint": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd" + "author_hint": "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4" } ], "participants": [ { "tag_index": 3, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "ws://localhost:21003"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "ws://localhost:21003"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": "ws://localhost:21003" }, { "tag_index": 4, - "raw_tag": ["p", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "wss://participant.relay.example?region=ca-bc"], - "pubkey": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "raw_tag": ["p", "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c", "wss://participant.relay.example?region=ca-bc"], + "pubkey": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c", "relay": "wss://participant.relay.example?region=ca-bc" }, { "tag_index": 5, - "raw_tag": ["p", "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"], - "pubkey": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "raw_tag": ["p", "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4"], + "pubkey": "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4", "relay": null } ], @@ -829,7 +829,7 @@ "id": "project_signed_nip10_malformed_relay_authorities", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"715bf99c903fcc3ff2f78411de07df916ab6b4476142c4f6974cf5eeddcabfd5\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000021,\"kind\":1,\"tags\":[[\"e\",\"3333333333333333333333333333333333333333333333333333333333333333\",\"wss://%\",\"\",\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\"],[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"wss://%zz\",\"root\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"],[\"e\",\"2222222222222222222222222222222222222222222222222222222222222222\",\"wss://256.1.1.1\",\"reply\",\"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"wss://[v1.foo]\"],[\"p\",\"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\"],[\"p\",\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\"]],\"content\":\"Malformed relay authorities\",\"sig\":\"37644f8a4b353d758aa1ce78f78fd17c702c4fd862b0408c3c61000ef9533150dc4888ef78b1023f6ee26b0abe786e31e9cc442f62c12260af04750b58f3f20e\"}" + "event_json": "{\"id\":\"fe9fbccea1eb7daf0b7fe3bce5507c5973617b82e8134f2fab82c726bf421ef3\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000021,\"kind\":1,\"tags\":[[\"e\",\"3333333333333333333333333333333333333333333333333333333333333333\",\"wss://%\",\"\",\"5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4\"],[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"wss://%zz\",\"root\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"e\",\"2222222222222222222222222222222222222222222222222222222222222222\",\"wss://256.1.1.1\",\"reply\",\"1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\",\"wss://[v1.foo]\"],[\"p\",\"1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c\"],[\"p\",\"5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4\"]],\"content\":\"Malformed relay authorities\",\"sig\":\"9b179c47c13301bfe31f1d0027dcca7dabf1ebdcb0a0e6f7764cb767c346963c8b801549716f4422e22b8d9311c1bb840faa7751c651e1ad0746f76953617a95\"}" }, "expected": { "style": "marked", @@ -837,44 +837,44 @@ "direct": false, "root": { "tag_index": 1, - "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "wss://%zz", "root", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], + "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "wss://%zz", "root", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], "event_id": "1111111111111111111111111111111111111111111111111111111111111111", "relay": null, - "author_hint": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + "author_hint": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af" }, "parent": { "tag_index": 2, - "raw_tag": ["e", "2222222222222222222222222222222222222222222222222222222222222222", "wss://256.1.1.1", "reply", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"], + "raw_tag": ["e", "2222222222222222222222222222222222222222222222222222222222222222", "wss://256.1.1.1", "reply", "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c"], "event_id": "2222222222222222222222222222222222222222222222222222222222222222", "relay": null, - "author_hint": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + "author_hint": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c" }, "citations": [ { "tag_index": 0, - "raw_tag": ["e", "3333333333333333333333333333333333333333333333333333333333333333", "wss://%", "", "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"], + "raw_tag": ["e", "3333333333333333333333333333333333333333333333333333333333333333", "wss://%", "", "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4"], "event_id": "3333333333333333333333333333333333333333333333333333333333333333", "relay": null, - "author_hint": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd" + "author_hint": "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4" } ], "participants": [ { "tag_index": 3, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "wss://[v1.foo]"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "wss://[v1.foo]"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null }, { "tag_index": 4, - "raw_tag": ["p", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"], - "pubkey": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "raw_tag": ["p", "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c"], + "pubkey": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c", "relay": null }, { "tag_index": 5, - "raw_tag": ["p", "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"], - "pubkey": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "raw_tag": ["p", "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4"], + "pubkey": "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4", "relay": null } ], @@ -882,22 +882,22 @@ { "code": "reply_reference_relay_ignored", "tag_index": 0, - "raw_tag": ["e", "3333333333333333333333333333333333333333333333333333333333333333", "wss://%", "", "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"] + "raw_tag": ["e", "3333333333333333333333333333333333333333333333333333333333333333", "wss://%", "", "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4"] }, { "code": "reply_reference_relay_ignored", "tag_index": 1, - "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "wss://%zz", "root", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"] + "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "wss://%zz", "root", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"] }, { "code": "reply_reference_relay_ignored", "tag_index": 2, - "raw_tag": ["e", "2222222222222222222222222222222222222222222222222222222222222222", "wss://256.1.1.1", "reply", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"] + "raw_tag": ["e", "2222222222222222222222222222222222222222222222222222222222222222", "wss://256.1.1.1", "reply", "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c"] }, { "code": "reply_author_relay_ignored", "tag_index": 3, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "wss://[v1.foo]"] + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "wss://[v1.foo]"] } ] } @@ -906,7 +906,7 @@ "id": "project_signed_nip10_ambiguous_same_reference", "kind": "social.reply.project_verified_event.invalid", "input": { - "event_json": "{\"id\":\"86f19437493f84ecd999d1cd5890ff53fa157b99309f65c056de48e82a8c75bf\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000007,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"reply\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"Ambiguous\",\"sig\":\"730b282fadf78838f6dad8830711fff6cff5b6da0d3c42db49faf1ef547cf3908ec0c901e1ac7069f8c346e9ec73cea879830a8687e18d87e476a1e0f82a0ca7\"}" + "event_json": "{\"id\":\"8642b1d2380d0a52c13011863530f781da7654c37f8176645abf2eb08d39d24d\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000007,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"reply\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"Ambiguous\",\"sig\":\"1f61730dda3b1d00ff2f85701f3e928bfdbd9f1dff8ab2c0971413e03194718c1bba766e62738074ad245d2fae23ebeec2cd3ab45eb353dd82a116833139de42\"}" }, "expected": { "error": "reply_reference_ambiguous" @@ -945,7 +945,7 @@ "id": "project_signed_nip10_invalid_event_id", "kind": "social.reply.project_verified_event.invalid", "input": { - "event_json": "{\"id\":\"2c071cfb2696c8cb2e676564290007bcbc995d08a5404462f747d6ceb73194fe\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000009,\"kind\":1,\"tags\":[[\"e\",\"not-an-event-id\",\"\",\"root\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"Invalid event id\",\"sig\":\"712bed9b975b2742dbb4b241e70893c67fbd4debab110c7d44bf365500405cc9c5c39efa1f9a3260a3a57f10cd0b981d84c327ff4ae0f1afa21c6e9fc8f8b851\"}" + "event_json": "{\"id\":\"8847b627c9e8e07a6506fcd66e2db952b76d12128498093f149f7b166400b3d0\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000009,\"kind\":1,\"tags\":[[\"e\",\"not-an-event-id\",\"\",\"root\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"Invalid event id\",\"sig\":\"83e1bf2c28e54ef653d52b352f9f41693030f50e105d4d67027df357187e84343ab44ceb039e09c3e93806692a4b670a94f00e407eb86d86b9af20d5c92f5602\"}" }, "expected": { "error": "reply_event_id_invalid" @@ -955,7 +955,7 @@ "id": "project_signed_nip10_author_hint_mismatch", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"a54d89f21c0a80df592eab60b07b0800ea5bd212fbe17d0f9deb852c109775a9\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000010,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"],[\"p\",\"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\"]],\"content\":\"Author mismatch\",\"sig\":\"3a9b2af22a1b63a1bf6a4cdf0f83497a199ff6f5edc5b1ea9fd0a70c4dd12034431e3992be9ee80827cd0f396e70d0a9f0c316408a269c80949cb5a0cf59c5f7\"}" + "event_json": "{\"id\":\"24e1807536ffe4dcdb01267f6eca1e53bf34c3e2d20a13111b864d5af8b14c43\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000010,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"p\",\"1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c\"]],\"content\":\"Author mismatch\",\"sig\":\"ae4be83e55311c831de6e47fb070b42bd92632010eca8f045519fddccdb029ebfbe8e7a4d58885522d1a4fc18cb43c6e3f5db8ecb6a11ec5f536e3a3a74c5c61\"}" }, "expected": { "style": "marked", @@ -963,18 +963,18 @@ "direct": true, "root": { "tag_index": 0, - "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "", "root", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], + "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "", "root", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], "event_id": "1111111111111111111111111111111111111111111111111111111111111111", "relay": null, - "author_hint": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + "author_hint": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af" }, "parent": null, "citations": [], "participants": [ { "tag_index": 1, - "raw_tag": ["p", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"], - "pubkey": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "raw_tag": ["p", "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c"], + "pubkey": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c", "relay": null } ], @@ -982,7 +982,7 @@ { "code": "reply_author_mismatch_ignored", "tag_index": 0, - "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "", "root", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"] + "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "", "root", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"] } ] } @@ -991,7 +991,7 @@ "id": "project_signed_nip10_blank_content", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"bb57163b91910e28747d2ea50c89a84fc4d72ce0509d87e97492518f71081d39\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000013,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"\",\"sig\":\"b1833129fc7568362e5c308a3d4b44b09c5d7b7c474b1335cb9a332e9167689678c009547f312b5bc79442bd018ed8ed2af6c64eafd3112bb96e154d6b7b4b48\"}" + "event_json": "{\"id\":\"399f0d0258c1546392643f1fab84fa4ee5fc6cfaf28608f6dff48c027c1f1ec4\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000013,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"\",\"sig\":\"d0409197aa610b8febfea4fb527355b8f43021298c272cd1978a5f9e3edd75d2f08a6cc96fa32d2a3b70026a0403b285813231558cf8cddaffd0a1a3bf8426c7\"}" }, "expected": { "style": "marked", @@ -1009,8 +1009,8 @@ "participants": [ { "tag_index": 1, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null } ], @@ -1021,7 +1021,7 @@ "id": "project_signed_nip10_invalid_author_hint_tolerated", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"64a50435d0e23c12ae6e52b0eddcd0e9a8efb07f0c59e2b41f839a30b9593d56\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000014,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\",\"not-a-pubkey\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"Malformed optional author\",\"sig\":\"3a554dd47779861e5c020bdcad2103b4831eaf7930b8a801bb99d7c0bcd898ef1a4a79aa8a3856533ab1b88bed0b2a8c44afafa6118daf8b172d502e22eeb95f\"}" + "event_json": "{\"id\":\"d4d58ea56554e78570dc2d75507b1211879002d69b902787b02e93b864315c09\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000014,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\",\"not-a-pubkey\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"Malformed optional author\",\"sig\":\"072e5c49445db582f80620d45e07836bd76860de7b347c48259bc94d718b04b89c02cce87dee6e32b27137a218b7fe0a387856e81b6268bf8bcb3fe0e5ab2f9f\"}" }, "expected": { "style": "marked", @@ -1039,8 +1039,8 @@ "participants": [ { "tag_index": 1, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null } ], @@ -1086,7 +1086,7 @@ "id": "project_signed_nip10_lone_reply_marker", "kind": "social.reply.project_verified_event.invalid", "input": { - "event_json": "{\"id\":\"eb5f2eea6aa74ffcbd758cb5fb72749babcad7343717cb30caac19200154f03a\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000011,\"kind\":1,\"tags\":[[\"e\",\"2222222222222222222222222222222222222222222222222222222222222222\",\"\",\"reply\"],[\"p\",\"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\"]],\"content\":\"Lone reply\",\"sig\":\"b4f2d2a564f248fc7012e427a1fea9267de728342485c3f8a4f19066cd15e4295b14a51f7aab898d38e61a5c86d134a80863e6ae1394081b4d9e368dee65e94b\"}" + "event_json": "{\"id\":\"e5822b15847a9952e156f9c46b3e1a3673da63e6ed72035a9088722c3bbfa3df\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000011,\"kind\":1,\"tags\":[[\"e\",\"2222222222222222222222222222222222222222222222222222222222222222\",\"\",\"reply\"],[\"p\",\"1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c\"]],\"content\":\"Lone reply\",\"sig\":\"0b4f90ad15407fd37119ae1e6c34e9c00c200790735fe457c19f53a45576a5cd444fd1506bd0e4d3b5ad50c1905e4022cc901ae74de42d78e5f68d018ac6f977\"}" }, "expected": { "error": "reply_marker_count" @@ -1096,7 +1096,7 @@ "id": "project_signed_nip10_unknown_marker", "kind": "social.reply.project_verified_event.invalid", "input": { - "event_json": "{\"id\":\"266e800a1a46fefad41fd745d3750eac53e5527339be4aa0b28f0fb8ebe34bea\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000012,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"mention\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"Unknown marker\",\"sig\":\"fd06119aad71aef0851c900fed068540ca6dde40ccfb8fc70c74cf8d10f0fdd13aac49863753fa8f1fd679c1890ba410259a291780682cc3f8fcf5b89e381afe\"}" + "event_json": "{\"id\":\"69f5cd728b45ee3688d949c318c4b46a1a7320d8f700b289339e537235007968\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000012,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"mention\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"Unknown marker\",\"sig\":\"52a5d203bd422ba9c2962093d09bdf03d8fd02eaa5ab4eb518888e1fcf9db7a13e6d305e356baa1a6edf36f9752cc1830c9d7f9493d705fad6655e5d580571f5\"}" }, "expected": { "error": "reply_marker_missing" @@ -1106,7 +1106,7 @@ "id": "admit_signed_nip10_marked_direct", "kind": "social.reply.verify_and_admit_event.valid", "input": { - "event_json": "{\"id\":\"2340fc3fec291f4d4429bf13bf23cc3b7ec8589aa5e6426a5fc5a25bfcf1a896\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000001,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"Direct reply\",\"sig\":\"16afb66cf2e30450a1055d697044b0f27835352553f32f7ac8d18387cc27861dfde3bb820a8882c00f933c13d4c967df5d5db986cc228a80dd3d291841bf08cd\"}" + "event_json": "{\"id\":\"d62b9340ac9808fc84a751788d017344ede91aea1c89081be3f7bff4a2266354\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000001,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"Direct reply\",\"sig\":\"206758bee31328a53457e3190b046a4a184941223f4e8ed1696db28d71c9af03138fe9add32d5e97d6f3b50bd0f78e4d5a91629dbf4d12aedd4315ce96c97e8c\"}" }, "expected": { "contract_id": "radroots.social.reply.v1", @@ -1118,7 +1118,7 @@ "id": "admit_signed_nip10_positional_direct", "kind": "social.reply.verify_and_admit_event.valid", "input": { - "event_json": "{\"id\":\"802da76963580d5932a400a2e56e73caccb80c78d43845c62f5fd95feee600e8\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000003,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"Legacy direct reply\",\"sig\":\"9a1a958170b2faf3c467bf174e776f7f61bf886644657cc12d92d6a9782db89f273508e1d940412645bbb73a6ce7948b7d20daa77647aa5fd8f9e164159826e7\"}" + "event_json": "{\"id\":\"a7141da919755d6ace9b5fa400928d512b4ef785c0ec03d55989bc2d6cbce860\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000003,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"Legacy direct reply\",\"sig\":\"eb2112223ed35f4b0919578a4981e08b403779391f6f9a831ea51763779028d85f72ce8224b1ae469ad6baea21d1d275210bb438a126b4391dab0c347051917a\"}" }, "expected": { "contract_id": "radroots.social.reply.v1", @@ -1130,7 +1130,7 @@ "id": "admit_signed_nip10_invalid_signature", "kind": "social.reply.verify_and_admit_event.invalid", "input": { - "event_json": "{\"id\":\"2340fc3fec291f4d4429bf13bf23cc3b7ec8589aa5e6426a5fc5a25bfcf1a896\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000001,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"Direct reply\",\"sig\":\"06afb66cf2e30450a1055d697044b0f27835352553f32f7ac8d18387cc27861dfde3bb820a8882c00f933c13d4c967df5d5db986cc228a80dd3d291841bf08cd\"}" + "event_json": "{\"id\":\"d62b9340ac9808fc84a751788d017344ede91aea1c89081be3f7bff4a2266354\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000001,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"Direct reply\",\"sig\":\"006758bee31328a53457e3190b046a4a184941223f4e8ed1696db28d71c9af03138fe9add32d5e97d6f3b50bd0f78e4d5a91629dbf4d12aedd4315ce96c97e8c\"}" }, "expected": { "error": "signature_invalid" diff --git a/contracts/conformance/vectors/profile/verified_event.v1.json b/contracts/conformance/vectors/profile/verified_event.v1.json @@ -4,12 +4,12 @@ "vectors": [ { "expected": { - "event_id": "a07878757d705d3cd848b9264791d699069068a5f0a575112f351367b0987958", + "event_id": "407b62d3d2c91737c4cba8352ec844b2c5cdd2c9dd441edd93a3c70cdbf8d7e7", "kind": 65535 }, "id": "event_verify_max_kind_001", "input": { - "event_json": "{\"id\":\"a07878757d705d3cd848b9264791d699069068a5f0a575112f351367b0987958\",\"pubkey\":\"1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f\",\"created_at\":1800000104,\"kind\":65535,\"tags\":[],\"content\":\"maximum-kind\",\"sig\":\"d79b19843a0bfd769c02c73866d44a3a06f7b11e107a5257971b60e700aa25565802fd3a7eed4042fe8db7d709a465e5f61478eb8291178831bf48f6b0980671\"}" + "event_json": "{\"id\":\"407b62d3d2c91737c4cba8352ec844b2c5cdd2c9dd441edd93a3c70cdbf8d7e7\",\"pubkey\":\"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df\",\"created_at\":1800000104,\"kind\":65535,\"tags\":[],\"content\":\"maximum-kind\",\"sig\":\"d1791afa8b3428151e6d6c8425842bcc68ebbce202bb6abb24976ad514794f8df5b4602cf69eee26fb20b7afcb249fb7a0eac5c953839838bccdb03bd1212ab6\"}" }, "kind": "event.verify_nip01.valid" }, @@ -19,7 +19,7 @@ }, "id": "event_verify_id_mismatch_001", "input": { - "event_json": "{\"content\":\"{\\\"display_name\\\":\\\"Moss Street Farm\\\",\\\"bot\\\":false,\\\"website\\\":\\\"https://mossstreet.example\\\",\\\"picture\\\":42}\",\"created_at\":1800000100,\"id\":\"fdcebf1cbdcddea8027b5e214cb7b223fa662d8b85f5d68acf2e8849be0d71c4\",\"kind\":0,\"pubkey\":\"1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f\",\"sig\":\"e5448d11671bcf73aa8d56941aff9df46d4e9fb250596671950e5f3c9d747440523efd33d8b9ff4f2a2ef1bd4b79e0a7cf5850132172b1db4b642ef2b348f721\",\"tags\":[]}" + "event_json": "{\"content\":\"{\\\"display_name\\\":\\\"Moss Street Farm\\\",\\\"bot\\\":false,\\\"website\\\":\\\"https://mossstreet.example\\\",\\\"picture\\\":42}\",\"created_at\":1800000100,\"id\":\"062bee187e9e645b81ec26ade05a69b5e8398caf527be8de0d9a45311ed0c7a0\",\"kind\":0,\"pubkey\":\"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df\",\"sig\":\"4290da0bb6422986647bc8cd5f63bd52d49f41e7b665d3b47105b8109183e8d596f322c531d4061df53e1d2b70fda12d5d1c14f3720d7a56d9d0a03746af5109\",\"tags\":[]}" }, "kind": "event.verify_nip01.invalid_id" }, @@ -29,19 +29,19 @@ }, "id": "event_verify_signature_invalid_001", "input": { - "event_json": "{\"content\":\"{\\\"display_name\\\":\\\"Moss Street Farm\\\",\\\"bot\\\":false,\\\"website\\\":\\\"https://mossstreet.example\\\",\\\"picture\\\":42}\",\"created_at\":1800000100,\"id\":\"b0450c4fb0a82cc829159646f90dc548503e8b7f850a434fd9ea58bf1b8d677f\",\"kind\":0,\"pubkey\":\"1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f\",\"sig\":\"d015e365c530c44fbc33e970af13616e482fafe65d0947edcdaa1e7b3038e9285b4b6826bdf454e8381d66e9dc6978d9974358572d97850ebc726fcc539e2b88\",\"tags\":[]}" + "event_json": "{\"content\":\"{\\\"display_name\\\":\\\"Moss Street Farm\\\",\\\"bot\\\":false,\\\"website\\\":\\\"https://mossstreet.example\\\",\\\"picture\\\":42}\",\"created_at\":1800000100,\"id\":\"762bee187e9e645b81ec26ade05a69b5e8398caf527be8de0d9a45311ed0c7a0\",\"kind\":0,\"pubkey\":\"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df\",\"sig\":\"0290da0bb6422986647bc8cd5f63bd52d49f41e7b665d3b47105b8109183e8d596f322c531d4061df53e1d2b70fda12d5d1c14f3720d7a56d9d0a03746af5109\",\"tags\":[]}" }, "kind": "event.verify_nip01.invalid_signature" }, { "expected": { - "error": "malformed_envelope" + "error": "invalid_public_key" }, "id": "event_verify_malformed_curve_pubkey_001", "input": { "event_json": "{\"id\":\"8d71bc1e4126e8b16c7e9229487d9028df9508c156d5e501d1487eda799af161\",\"pubkey\":\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\",\"created_at\":1800000107,\"kind\":0,\"tags\":[],\"content\":\"malformed-curve-pubkey\",\"sig\":\"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}" }, - "kind": "event.verify_nip01.malformed_envelope" + "kind": "event.wire.invalid_public_key" }, { "expected": { @@ -50,13 +50,13 @@ }, "id": "event_verify_kind_overflow_001", "input": { - "event_json": "{\"content\":\"overflow-kind\",\"created_at\":1800000106,\"id\":\"82dff74958bd7e1e52ad98add08bbb70d4ce9cf9d90e4741c64c212df0804ccb\",\"kind\":65536,\"pubkey\":\"1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f\",\"sig\":\"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"tags\":[]}" + "event_json": "{\"content\":\"overflow-kind\",\"created_at\":1800000106,\"id\":\"ecb111a334b5d374db240f42c32fd57ce61f42d4bbe1c1d88b62ed72755f906c\",\"kind\":65536,\"pubkey\":\"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df\",\"sig\":\"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"tags\":[]}" }, "kind": "event.verify_nip01.kind_overflow" }, { "expected": { - "event_id": "b0450c4fb0a82cc829159646f90dc548503e8b7f850a434fd9ea58bf1b8d677f", + "event_id": "762bee187e9e645b81ec26ade05a69b5e8398caf527be8de0d9a45311ed0c7a0", "projected": { "bot": false, "display_name": "Moss Street Farm" @@ -69,7 +69,7 @@ }, "id": "profile_admit_tagless_tolerant_001", "input": { - "event_json": "{\"id\":\"b0450c4fb0a82cc829159646f90dc548503e8b7f850a434fd9ea58bf1b8d677f\",\"pubkey\":\"1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f\",\"created_at\":1800000100,\"kind\":0,\"tags\":[],\"content\":\"{\\\"display_name\\\":\\\"Moss Street Farm\\\",\\\"bot\\\":false,\\\"website\\\":\\\"https://mossstreet.example\\\",\\\"picture\\\":42}\",\"sig\":\"e5448d11671bcf73aa8d56941aff9df46d4e9fb250596671950e5f3c9d747440523efd33d8b9ff4f2a2ef1bd4b79e0a7cf5850132172b1db4b642ef2b348f721\"}" + "event_json": "{\"id\":\"762bee187e9e645b81ec26ade05a69b5e8398caf527be8de0d9a45311ed0c7a0\",\"pubkey\":\"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df\",\"created_at\":1800000100,\"kind\":0,\"tags\":[],\"content\":\"{\\\"display_name\\\":\\\"Moss Street Farm\\\",\\\"bot\\\":false,\\\"website\\\":\\\"https://mossstreet.example\\\",\\\"picture\\\":42}\",\"sig\":\"4290da0bb6422986647bc8cd5f63bd52d49f41e7b665d3b47105b8109183e8d596f322c531d4061df53e1d2b70fda12d5d1c14f3720d7a56d9d0a03746af5109\"}" }, "kind": "profile.verify_and_admit.valid" }, @@ -80,7 +80,7 @@ }, "id": "profile_admit_wrong_kind_001", "input": { - "event_json": "{\"id\":\"05b2ebdf444f09330198f8c07ea3e3c7d8ac97d94c41e957b74bce921f611080\",\"pubkey\":\"1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f\",\"created_at\":1800000102,\"kind\":1,\"tags\":[],\"content\":\"{\\\"name\\\":\\\"not-a-profile\\\"}\",\"sig\":\"3d12c2dfea5cff7e9993166d20b9092f4a6a9dd7e9f4af26355d2f4c4fa0e1ba7a0e5fe6e4b90c93ae57d52cc71b38b409051702200868dfd601dbdd74b89710\"}" + "event_json": "{\"id\":\"530131615015d1631d89c80e5cbde5487ce44de24d1164e7d9d8be86f47f1399\",\"pubkey\":\"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df\",\"created_at\":1800000102,\"kind\":1,\"tags\":[],\"content\":\"{\\\"name\\\":\\\"not-a-profile\\\"}\",\"sig\":\"1e62c75d7cd1427ce03728ebc27413c284a9c72a0c1049ea6e537ccf7f1a3ed139718468c3f0cf78dc2da7d22ccf35843463272d8f42f59bccd69ffebb8ef3bf\"}" }, "kind": "profile.verify_and_admit.invalid_kind" }, @@ -90,19 +90,19 @@ }, "id": "profile_admit_non_object_001", "input": { - "event_json": "{\"id\":\"671f2d9f80a2fa2759c9514ae36fd18296cee71417fc86995525f2c659a5f781\",\"pubkey\":\"1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f\",\"created_at\":1800000103,\"kind\":0,\"tags\":[],\"content\":\"[]\",\"sig\":\"67d0420384e366407499ce4ab501cd87a02bea0d4221007b7a3ff01d9b68a0b9d372882184ab48775a8516f6a6554b506fc3e7652162a53e08a43e63daeacac7\"}" + "event_json": "{\"id\":\"6205ecbaead32e5bb64afa301446f3ba9cf47d3113b23db6978800f47e5e4183\",\"pubkey\":\"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df\",\"created_at\":1800000103,\"kind\":0,\"tags\":[],\"content\":\"[]\",\"sig\":\"909f64b7b5393a80e7db8d0aa788d301133f966c23346e71ca9c019f8b7ac297fe7e27b5049410d60f5858c9060bc7e86fcf8b165c53da2c45f200a00b03f98f\"}" }, "kind": "profile.verify_and_admit.invalid_metadata" }, { "expected": { "created_at": 1800000105, - "event_id": "ad00fc208cc7036b95fadb7a4660bc600aa007502430250630d70d15b50695b3" + "event_id": "73956f3c723129dbe43ec2865261f6de04632b2817daede8b3cc47ab93faac3f" }, "id": "profile_equal_time_lowest_id_001", "input": { - "first_event_json": "{\"id\":\"fdcebf1cbdcddea8027b5e214cb7b223fa662d8b85f5d68acf2e8849be0d71c4\",\"pubkey\":\"1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f\",\"created_at\":1800000105,\"kind\":0,\"tags\":[],\"content\":\"{\\\"name\\\":\\\"arrival-a\\\"}\",\"sig\":\"445a4a08bd365acbe3d68b1433cd8952f8974cb1f454c7d6790881b123c1e7a6449662f78e3044436c7cda8745ae74aa8ee382e292160a3a3f420dd3bb4f275c\"}", - "second_event_json": "{\"id\":\"ad00fc208cc7036b95fadb7a4660bc600aa007502430250630d70d15b50695b3\",\"pubkey\":\"1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f\",\"created_at\":1800000105,\"kind\":0,\"tags\":[],\"content\":\"{\\\"name\\\":\\\"arrival-b\\\"}\",\"sig\":\"6b52cb1cbcf2639104b564144517d8479833272690514af9e9d45b170a1c88320ac3425b9339aa525e591584f97666b1c556b4709fb6ef27959775e70c8caabe\"}" + "first_event_json": "{\"id\":\"73956f3c723129dbe43ec2865261f6de04632b2817daede8b3cc47ab93faac3f\",\"pubkey\":\"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df\",\"created_at\":1800000105,\"kind\":0,\"tags\":[],\"content\":\"{\\\"name\\\":\\\"arrival-a\\\"}\",\"sig\":\"18c2196e1f9eba23147f138f2ee2e5b140bbfc48ec37f72f4919c28d2d03eaeb60269fe7c6d61a8d93f5d25e05a94f5f87dc1a449850b239114bb7fe76cd6190\"}", + "second_event_json": "{\"id\":\"e6e8ff39b7e4365d8fd89a8d47fb6c4e33ce364a449aeb108d5219b4f5d23658\",\"pubkey\":\"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df\",\"created_at\":1800000105,\"kind\":0,\"tags\":[],\"content\":\"{\\\"name\\\":\\\"arrival-b\\\"}\",\"sig\":\"0b87cc548732f65032187fe33e1f357fd8fe4d1d4c6ec3a2ee8e42713f6bfa73c12f2e6740374ec11b1f318d78c07730dc495abbe50ba025dfbe697041297a22\"}" }, "kind": "profile.select_equal_time_head" } diff --git a/crates/authority/Cargo.toml b/crates/authority/Cargo.toml @@ -12,7 +12,7 @@ homepage.workspace = true [features] default = ["std"] -std = ["radroots_event/std"] +std = ["radroots_event/std", "radroots_identity/std"] local_signer = [ "std", "dep:radroots_nostr", @@ -22,6 +22,7 @@ local_signer = [ [dependencies] radroots_event = { workspace = true, default-features = false } +radroots_identity = { workspace = true, default-features = false } radroots_nostr = { workspace = true, optional = true, default-features = false } [dev-dependencies] diff --git a/crates/authority/src/actor.rs b/crates/authority/src/actor.rs @@ -3,7 +3,7 @@ use crate::RadrootsAuthorityError; use core::{fmt, str::FromStr}; use radroots_event::contract::RadrootsActorRole; -use radroots_event::ids::RadrootsPublicKey; +use radroots_identity::PublicKey; #[cfg(not(feature = "std"))] use alloc::{collections::BTreeSet, string::String}; @@ -99,7 +99,7 @@ pub enum RadrootsActorSource { pub enum RadrootsActorSelector { SelectedAccount, AccountId(RadrootsActorAccountId), - PublicKey(RadrootsPublicKey), + PublicKey(PublicKey), DraftExpectedPubkey, } @@ -109,7 +109,7 @@ impl RadrootsActorSelector { } pub fn public_key(pubkey: impl AsRef<str>) -> Result<Self, RadrootsAuthorityError> { - let pubkey = RadrootsPublicKey::parse(pubkey.as_ref()) + let pubkey = PublicKey::from_hex(pubkey.as_ref()) .map_err(|_| RadrootsAuthorityError::InvalidActorPubkey)?; Ok(Self::PublicKey(pubkey)) } @@ -150,7 +150,7 @@ impl RadrootsActorResolutionRequest { #[derive(Clone, Debug, PartialEq, Eq)] pub struct RadrootsActorContext { - pubkey: RadrootsPublicKey, + pubkey: PublicKey, roles: BTreeSet<RadrootsActorRole>, account_id: Option<RadrootsActorAccountId>, source: RadrootsActorSource, @@ -231,7 +231,7 @@ impl RadrootsActorContext { where I: IntoIterator<Item = RadrootsActorRole>, { - let pubkey = RadrootsPublicKey::parse(pubkey.as_ref()) + let pubkey = PublicKey::from_hex(pubkey.as_ref()) .map_err(|_| RadrootsAuthorityError::InvalidActorPubkey)?; Ok(Self { pubkey, @@ -241,7 +241,7 @@ impl RadrootsActorContext { }) } - pub fn pubkey(&self) -> &RadrootsPublicKey { + pub fn pubkey(&self) -> &PublicKey { &self.pubkey } @@ -276,13 +276,13 @@ pub fn role_satisfies( mod tests { use super::*; - fn hex_64(character: char) -> String { - std::iter::repeat_n(character, 64).collect() - } + const VALID_PUBKEY: &str = "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"; + const OTHER_VALID_PUBKEY: &str = + "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"; #[test] fn any_is_satisfied_by_any_actor_context() { - let actor = RadrootsActorContext::test(hex_64('a'), []).expect("actor"); + let actor = RadrootsActorContext::test(VALID_PUBKEY, []).expect("actor"); assert!(actor.satisfies(RadrootsActorRole::Any)); } @@ -290,7 +290,7 @@ mod tests { #[test] fn specific_roles_require_explicit_membership() { let actor = - RadrootsActorContext::test(hex_64('a'), [RadrootsActorRole::Farmer]).expect("actor"); + RadrootsActorContext::test(VALID_PUBKEY, [RadrootsActorRole::Farmer]).expect("actor"); assert!(actor.satisfies(RadrootsActorRole::Farmer)); assert!(!actor.satisfies(RadrootsActorRole::Seller)); @@ -299,7 +299,7 @@ mod tests { #[test] fn farmer_does_not_globally_satisfy_seller() { let actor = - RadrootsActorContext::test(hex_64('a'), [RadrootsActorRole::Farmer]).expect("actor"); + RadrootsActorContext::test(VALID_PUBKEY, [RadrootsActorRole::Farmer]).expect("actor"); assert!(!actor.satisfies(RadrootsActorRole::Seller)); } @@ -307,7 +307,7 @@ mod tests { #[test] fn multi_role_actors_satisfy_each_assigned_role() { let actor = RadrootsActorContext::test( - hex_64('a'), + VALID_PUBKEY, [RadrootsActorRole::Farmer, RadrootsActorRole::Seller], ) .expect("actor"); @@ -320,14 +320,14 @@ mod tests { #[test] fn local_account_context_carries_validated_account_id() { let actor = RadrootsActorContext::local_account( - hex_64('a'), + VALID_PUBKEY, "acct-field-01", [RadrootsActorRole::Farmer], ) .expect("actor"); assert_eq!(actor.source(), RadrootsActorSource::LocalAccount); - assert_eq!(actor.pubkey().as_str(), hex_64('a')); + assert_eq!(actor.pubkey().to_hex(), VALID_PUBKEY); assert_eq!( actor.roles().iter().copied().collect::<Vec<_>>(), vec![RadrootsActorRole::Farmer] @@ -339,8 +339,9 @@ mod tests { #[test] fn explicit_pubkey_context_has_no_account_id() { - let actor = RadrootsActorContext::explicit_pubkey(hex_64('a'), [RadrootsActorRole::Seller]) - .expect("actor"); + let actor = + RadrootsActorContext::explicit_pubkey(VALID_PUBKEY, [RadrootsActorRole::Seller]) + .expect("actor"); assert_eq!(actor.source(), RadrootsActorSource::ExplicitPubkey); assert_eq!(actor.account_id(), None); @@ -349,7 +350,7 @@ mod tests { #[test] fn test_context_has_no_account_id() { let actor = - RadrootsActorContext::test(hex_64('a'), [RadrootsActorRole::Farmer]).expect("actor"); + RadrootsActorContext::test(VALID_PUBKEY, [RadrootsActorRole::Farmer]).expect("actor"); assert_eq!(actor.source(), RadrootsActorSource::Test); assert_eq!(actor.account_id(), None); @@ -358,14 +359,17 @@ mod tests { #[test] fn remote_signer_and_service_contexts_carry_account_ids() { let remote = RadrootsActorContext::remote_signer( - hex_64('a'), + VALID_PUBKEY, "acct-remote", [RadrootsActorRole::Buyer], ) .expect("remote actor"); - let service = - RadrootsActorContext::service(hex_64('b'), "acct-service", [RadrootsActorRole::Any]) - .expect("service actor"); + let service = RadrootsActorContext::service( + OTHER_VALID_PUBKEY, + "acct-service", + [RadrootsActorRole::Any], + ) + .expect("service actor"); assert_eq!(remote.source(), RadrootsActorSource::RemoteSigner); assert_eq!( @@ -382,20 +386,20 @@ mod tests { #[test] fn account_id_rejects_invalid_values() { assert!(matches!( - RadrootsActorContext::local_account(hex_64('a'), "", []), + RadrootsActorContext::local_account(VALID_PUBKEY, "", []), Err(RadrootsAuthorityError::InvalidActorAccountIdEmpty) )); assert!(matches!( - RadrootsActorContext::local_account(hex_64('a'), " account ", []), + RadrootsActorContext::local_account(VALID_PUBKEY, " account ", []), Err(RadrootsAuthorityError::InvalidActorAccountIdUntrimmed) )); assert!(matches!( - RadrootsActorContext::local_account(hex_64('a'), "account\nid", []), + RadrootsActorContext::local_account(VALID_PUBKEY, "account\nid", []), Err(RadrootsAuthorityError::InvalidActorAccountIdControlCharacter) )); assert!(matches!( RadrootsActorContext::local_account( - hex_64('a'), + VALID_PUBKEY, core::iter::repeat_n('a', MAX_ACTOR_ACCOUNT_ID_LEN + 1).collect::<String>(), [] ), @@ -455,7 +459,7 @@ mod tests { RadrootsActorSelector::SelectedAccount )); assert!(matches!( - RadrootsActorSelector::public_key(hex_64('b')).expect("selector"), + RadrootsActorSelector::public_key(OTHER_VALID_PUBKEY).expect("selector"), RadrootsActorSelector::PublicKey(_) )); assert!(matches!( diff --git a/crates/authority/src/authorization.rs b/crates/authority/src/authorization.rs @@ -45,10 +45,10 @@ pub fn authorize_actor_for_draft( }); } authorize_actor_for_contract(actor, contract)?; - if actor.pubkey().as_str() != draft.expected_pubkey_str() { + if actor.pubkey() != draft.expected_pubkey() { return Err(RadrootsAuthorityError::ActorPubkeyMismatch { - expected_pubkey: draft.expected_pubkey_str().to_owned(), - actor_pubkey: actor.pubkey().as_str().to_owned(), + expected_pubkey: draft.expected_pubkey().to_hex().to_owned(), + actor_pubkey: actor.pubkey().to_hex(), }); } Ok(contract) @@ -61,12 +61,12 @@ pub fn authorize_signer_for_draft<S>( where S: RadrootsEventSigner + ?Sized, { - if signer.pubkey().as_str() == draft.expected_pubkey_str() { + if signer.pubkey() == draft.expected_pubkey() { Ok(()) } else { Err(RadrootsAuthorityError::SignerPubkeyMismatch { - expected_pubkey: draft.expected_pubkey_str().to_owned(), - signer_pubkey: signer.pubkey().as_str().to_owned(), + expected_pubkey: draft.expected_pubkey().to_hex().to_owned(), + signer_pubkey: signer.pubkey().to_hex(), }) } } @@ -173,8 +173,11 @@ mod tests { use radroots_event::contract::{ RADROOTS_EVENT_CONTRACT_REGISTRY_VERSION, RadrootsActorRole, event_contract, }; - use radroots_event::ids::RadrootsPublicKey; use radroots_event::kinds::{KIND_CLASSIFIED_LISTING, KIND_POST, KIND_TRADE_PROPOSAL}; + use radroots_identity::PublicKey; + + const OTHER_VALID_PUBKEY: &str = + "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"; fn hex_64(character: char) -> String { std::iter::repeat_n(character, 64).collect() @@ -236,14 +239,14 @@ mod tests { } struct StaticSigner { - pubkey: RadrootsPublicKey, + pubkey: PublicKey, overrides: SignedEventOverrides, } impl StaticSigner { fn new(pubkey: &str) -> Self { Self { - pubkey: RadrootsPublicKey::parse(pubkey).expect("pubkey"), + pubkey: PublicKey::from_hex(pubkey).expect("pubkey"), overrides: SignedEventOverrides::default(), } } @@ -260,14 +263,14 @@ mod tests { fn with_overrides(pubkey: &str, overrides: SignedEventOverrides) -> Self { Self { - pubkey: RadrootsPublicKey::parse(pubkey).expect("pubkey"), + pubkey: PublicKey::from_hex(pubkey).expect("pubkey"), overrides, } } } impl RadrootsEventSigner for StaticSigner { - fn pubkey(&self) -> &RadrootsPublicKey { + fn pubkey(&self) -> &PublicKey { &self.pubkey } @@ -317,21 +320,21 @@ mod tests { } struct CountingSigner { - pubkey: RadrootsPublicKey, + pubkey: PublicKey, sign_invocations: Cell<usize>, } impl CountingSigner { fn new(pubkey: &str) -> Self { Self { - pubkey: RadrootsPublicKey::parse(pubkey).expect("pubkey"), + pubkey: PublicKey::from_hex(pubkey).expect("pubkey"), sign_invocations: Cell::new(0), } } } impl RadrootsEventSigner for CountingSigner { - fn pubkey(&self) -> &RadrootsPublicKey { + fn pubkey(&self) -> &PublicKey { &self.pubkey } @@ -347,7 +350,7 @@ mod tests { fn signed_event_from_draft(draft: &RadrootsEventDraft) -> RadrootsSignedEvent { signed_event_from_parts( - draft.expected_pubkey_str().to_owned(), + draft.expected_pubkey().to_hex().to_owned(), draft.created_at_u64(), draft.kind_u32(), draft.tags_as_vec(), @@ -399,7 +402,7 @@ mod tests { let trade_decision = event_contract("radroots.trade.decision.v1").expect("trade decision contract"); let seller = seller_actor(hex_64('a').as_str()); - let buyer = buyer_actor(hex_64('b').as_str()); + let buyer = buyer_actor(OTHER_VALID_PUBKEY); assert_eq!(operational_listing.author_role, RadrootsActorRole::Seller); assert!(authorize_actor_for_contract(&seller, operational_listing).is_ok()); @@ -423,7 +426,7 @@ mod tests { #[test] fn actor_pubkey_mismatch_fails() { let draft = operational_listing_event_draft(hex_64('a').as_str()); - let actor = seller_actor(hex_64('b').as_str()); + let actor = seller_actor(OTHER_VALID_PUBKEY); assert!(matches!( authorize_actor_for_draft(&actor, &draft), @@ -434,7 +437,7 @@ mod tests { #[test] fn signer_pubkey_mismatch_fails() { let draft = operational_listing_event_draft(hex_64('a').as_str()); - let signer = StaticSigner::new(hex_64('b').as_str()); + let signer = StaticSigner::new(OTHER_VALID_PUBKEY); assert!(matches!( authorize_signer_for_draft(&signer, &draft), @@ -594,7 +597,7 @@ mod tests { let pubkey = hex_64('a'); let draft = operational_listing_event_draft(pubkey.as_str()); let signed = signed_event_from_parts( - hex_64('b'), + OTHER_VALID_PUBKEY.to_owned(), draft.created_at_u64(), draft.kind_u32(), draft.tags_as_vec(), @@ -641,7 +644,7 @@ mod tests { let signed = sign_authorized_draft(&actor, &signer, &draft).expect("signed"); assert_eq!(signed.id_str(), draft.expected_event_id_str()); - assert_eq!(signed.pubkey_str(), draft.expected_pubkey_str()); + assert_eq!(signed.pubkey().to_hex(), draft.expected_pubkey().to_hex()); assert_eq!(signed.kind(), KIND_CLASSIFIED_LISTING); } diff --git a/crates/authority/src/local_signer.rs b/crates/authority/src/local_signer.rs @@ -2,24 +2,24 @@ use crate::{RadrootsAuthorityError, RadrootsEventSigner, RadrootsSignerError}; use radroots_event::draft::{RadrootsEventDraft, RadrootsSignedEvent}; -use radroots_event::ids::RadrootsPublicKey; +use radroots_identity::PublicKey; use radroots_nostr::prelude::{RadrootsNostrKeys, radroots_nostr_sign_frozen_draft}; pub struct RadrootsLocalEventSigner { keys: RadrootsNostrKeys, - pubkey: RadrootsPublicKey, + pubkey: PublicKey, } impl RadrootsLocalEventSigner { pub fn new(keys: RadrootsNostrKeys) -> Result<Self, RadrootsAuthorityError> { - let pubkey = RadrootsPublicKey::parse(keys.public_key().to_hex()) + let pubkey = PublicKey::from_hex(&keys.public_key().to_hex()) .map_err(|_| RadrootsAuthorityError::InvalidSignerPubkey)?; Ok(Self { keys, pubkey }) } } impl RadrootsEventSigner for RadrootsLocalEventSigner { - fn pubkey(&self) -> &RadrootsPublicKey { + fn pubkey(&self) -> &PublicKey { &self.pubkey } @@ -75,7 +75,7 @@ mod tests { fn local_signer_reports_public_key() { let signer = RadrootsLocalEventSigner::new(fixture_keys()).expect("signer"); - assert_eq!(signer.pubkey().as_str(), FIXTURE_ALICE_PUBLIC_KEY_HEX); + assert_eq!(signer.pubkey().to_hex(), FIXTURE_ALICE_PUBLIC_KEY_HEX); } #[test] @@ -86,7 +86,7 @@ mod tests { let signed = signer.sign_frozen_draft(&draft).expect("signed"); assert_eq!(signed.id_str(), draft.expected_event_id_str()); - assert_eq!(signed.pubkey_str(), draft.expected_pubkey_str()); + assert_eq!(signed.pubkey().to_hex(), draft.expected_pubkey().to_hex()); assert_eq!( radroots_nostr_verify_event(&verification_event(&signed)), RadrootsNostrEventVerification::Verified diff --git a/crates/authority/src/signer.rs b/crates/authority/src/signer.rs @@ -2,29 +2,29 @@ use crate::{RadrootsAuthorityError, RadrootsSignerError}; use radroots_event::draft::{RadrootsEventDraft, RadrootsSignedEvent}; -use radroots_event::ids::RadrootsPublicKey; #[cfg(test)] use radroots_event::wire::RadrootsNip01EventWire; +use radroots_identity::PublicKey; #[derive(Clone, Debug, PartialEq, Eq)] pub struct RadrootsSignerIdentity { - pub pubkey: RadrootsPublicKey, + pub pubkey: PublicKey, } impl RadrootsSignerIdentity { pub fn new(pubkey: impl AsRef<str>) -> Result<Self, RadrootsAuthorityError> { - let pubkey = RadrootsPublicKey::parse(pubkey.as_ref()) + let pubkey = PublicKey::from_hex(pubkey.as_ref()) .map_err(|_| RadrootsAuthorityError::InvalidSignerPubkey)?; Ok(Self { pubkey }) } - pub fn pubkey(&self) -> &RadrootsPublicKey { + pub fn pubkey(&self) -> &PublicKey { &self.pubkey } } pub trait RadrootsEventSigner { - fn pubkey(&self) -> &RadrootsPublicKey; + fn pubkey(&self) -> &PublicKey; fn sign_frozen_draft( &self, @@ -58,7 +58,7 @@ mod tests { } struct MockSigner { - pubkey: RadrootsPublicKey, + pubkey: PublicKey, failure: Option<RadrootsSignerError>, event_id: Option<String>, } @@ -66,7 +66,7 @@ mod tests { impl MockSigner { fn new(pubkey: &str) -> Self { Self { - pubkey: RadrootsPublicKey::parse(pubkey).expect("pubkey"), + pubkey: PublicKey::from_hex(pubkey).expect("pubkey"), failure: None, event_id: None, } @@ -74,7 +74,7 @@ mod tests { fn failing(pubkey: &str, failure: RadrootsSignerError) -> Self { Self { - pubkey: RadrootsPublicKey::parse(pubkey).expect("pubkey"), + pubkey: PublicKey::from_hex(pubkey).expect("pubkey"), failure: Some(failure), event_id: None, } @@ -82,7 +82,7 @@ mod tests { fn with_event_id(pubkey: &str, event_id: String) -> Self { Self { - pubkey: RadrootsPublicKey::parse(pubkey).expect("pubkey"), + pubkey: PublicKey::from_hex(pubkey).expect("pubkey"), failure: None, event_id: Some(event_id), } @@ -90,7 +90,7 @@ mod tests { } impl RadrootsEventSigner for MockSigner { - fn pubkey(&self) -> &RadrootsPublicKey { + fn pubkey(&self) -> &PublicKey { &self.pubkey } @@ -151,14 +151,14 @@ mod tests { let pubkey = hex_64('a'); let signer = MockSigner::new(pubkey.as_str()); - assert_eq!(signer.pubkey().as_str(), pubkey); + assert_eq!(signer.pubkey().to_hex(), pubkey); } #[test] fn signer_identity_validates_public_key() { let pubkey = hex_64('a'); let identity = RadrootsSignerIdentity::new(pubkey.as_str()).expect("identity"); - assert_eq!(identity.pubkey().as_str(), pubkey); + assert_eq!(identity.pubkey().to_hex(), pubkey); assert!(matches!( RadrootsSignerIdentity::new("bad-pubkey"), @@ -175,7 +175,7 @@ mod tests { let signed = signer.sign_frozen_draft(&draft).expect("signed"); assert_eq!(signed.id_str(), draft.expected_event_id_str()); - assert_eq!(signed.pubkey_str(), pubkey); + assert_eq!(signed.pubkey().to_hex(), pubkey); assert_eq!(signed.kind(), KIND_GEOCHAT); } diff --git a/crates/event_codec/Cargo.toml b/crates/event_codec/Cargo.toml @@ -17,8 +17,18 @@ name = "radroots_event_codec" [features] default = ["std"] -std = ["radroots_blossom/std", "radroots_core/std", "radroots_event/std"] -serde = ["dep:serde", "radroots_core/serde", "radroots_event/serde"] +std = [ + "radroots_blossom/std", + "radroots_core/std", + "radroots_event/std", + "radroots_identity/std", +] +serde = [ + "dep:serde", + "radroots_core/serde", + "radroots_event/serde", + "radroots_identity/serde", +] serde_json = ["serde", "dep:serde_json"] nostr = ["dep:nostr", "std"] knowledge = ["serde_json", "radroots_event/knowledge"] @@ -29,6 +39,7 @@ contract-manifest = ["knowledge", "dep:hex", "dep:sha2"] radroots_blossom = { workspace = true, default-features = false } radroots_core = { workspace = true, default-features = false } radroots_event = { workspace = true, default-features = false } +radroots_identity = { workspace = true, default-features = false } serde = { workspace = true, default-features = false, features = [ "alloc", ], optional = true } diff --git a/crates/event_codec/src/admission.rs b/crates/event_codec/src/admission.rs @@ -317,7 +317,8 @@ mod tests { mod signed { use super::*; use crate::{ - test_fixtures::FIXTURE_ALICE_SECRET_KEY_HEX, verification::verify_nip01_event, + test_fixtures::{FIXTURE_ALICE_PUBLIC_KEY_HEX, FIXTURE_ALICE_SECRET_KEY_HEX}, + verification::verify_nip01_event, }; use nostr::secp256k1::Message; use nostr::{Keys, SECP256K1}; @@ -506,12 +507,22 @@ mod tests { fn comment_tags() -> Vec<Vec<String>> { vec![ - vec!["E".into(), "a".repeat(64), String::new(), "b".repeat(64)], + vec![ + "E".into(), + "a".repeat(64), + String::new(), + FIXTURE_ALICE_PUBLIC_KEY_HEX.into(), + ], vec!["K".into(), KIND_CLASSIFIED_LISTING.to_string()], - vec!["P".into(), "b".repeat(64)], - vec!["e".into(), "a".repeat(64), String::new(), "b".repeat(64)], + vec!["P".into(), FIXTURE_ALICE_PUBLIC_KEY_HEX.into()], + vec![ + "e".into(), + "a".repeat(64), + String::new(), + FIXTURE_ALICE_PUBLIC_KEY_HEX.into(), + ], vec!["k".into(), KIND_CLASSIFIED_LISTING.to_string()], - vec!["p".into(), "b".repeat(64)], + vec!["p".into(), FIXTURE_ALICE_PUBLIC_KEY_HEX.into()], ] } diff --git a/crates/event_codec/src/calendar/decode.rs b/crates/event_codec/src/calendar/decode.rs @@ -32,6 +32,7 @@ use radroots_event::{ DEFAULT_TAG_TOTAL_MAX_BYTES, }, }; +use radroots_identity::PublicKey; use crate::error::EventParseError; use crate::parsed::{RadrootsParsedData, RadrootsParsedEvent}; @@ -583,8 +584,7 @@ fn calendar_participants_from_tags( if !(2..=4).contains(&tag.len()) { return Err(EventParseError::InvalidTag("p")); } - radroots_event::ids::RadrootsPublicKey::parse(&tag[1]) - .map_err(|_| EventParseError::InvalidTag(TAG_P))?; + PublicKey::from_hex(&tag[1]).map_err(|_| EventParseError::InvalidTag(TAG_P))?; if tag.len() == 3 && tag[2].is_empty() { return Err(EventParseError::InvalidTag(TAG_P)); } diff --git a/crates/event_codec/src/calendar/encode.rs b/crates/event_codec/src/calendar/encode.rs @@ -288,7 +288,7 @@ fn push_calendar_author_reference( tags: &mut Vec<Vec<String>>, reference: &RadrootsCalendarEventAuthorReference, ) { - let mut tag = vec![TAG_P.to_string(), reference.pubkey().as_str().to_string()]; + let mut tag = vec![TAG_P.to_string(), reference.pubkey().to_hex()]; if let Some(relay) = reference.relay() { tag.push(relay.to_string()); } diff --git a/crates/event_codec/src/comment/authored.rs b/crates/event_codec/src/comment/authored.rs @@ -15,6 +15,7 @@ use radroots_event::{ relay_hint::RadrootsNostrRelayHint, wire::RadrootsNip01EventWireParts, }; +use radroots_identity::PublicKey; /// Builds deterministic unsigned kind-1111 wire parts for a strict NIP-22 /// comment. @@ -33,7 +34,7 @@ pub fn authored_nip22_comment_to_wire_parts( } } tags.push(vec!["K".to_string(), root.kind().as_u32().to_string()]); - tags.push(participant_tag("P", root.author().as_str(), root.relay())); + tags.push(participant_tag("P", root.author(), root.relay())); match (root, position) { ( @@ -42,11 +43,7 @@ pub fn authored_nip22_comment_to_wire_parts( ) => { tags.push(event_reference_tag("e", reference)); tags.push(vec!["k".to_string(), root.kind().as_u32().to_string()]); - tags.push(participant_tag( - "p", - reference.author().as_str(), - reference.relay(), - )); + tags.push(participant_tag("p", reference.author(), reference.relay())); } ( RadrootsNip22CommentRoot::Address(reference), @@ -59,20 +56,12 @@ pub fn authored_nip22_comment_to_wire_parts( reference.relay(), )); tags.push(vec!["k".to_string(), root.kind().as_u32().to_string()]); - tags.push(participant_tag( - "p", - reference.author().as_str(), - reference.relay(), - )); + tags.push(participant_tag("p", reference.author(), reference.relay())); } (_, RadrootsNip22CommentPosition::Nested { parent }) => { tags.push(parent_reference_tag(parent)); tags.push(vec!["k".to_string(), KIND_COMMENT.to_string()]); - tags.push(participant_tag( - "p", - parent.author().as_str(), - parent.relay(), - )); + tags.push(participant_tag("p", parent.author(), parent.relay())); } _ => unreachable!("authored Comment constructors preserve root and position compatibility"), } @@ -89,7 +78,7 @@ fn event_reference_tag(name: &str, reference: &RadrootsNip22EventRootReference) name.to_string(), reference.event_id().as_str().to_string(), reference.relay_or_empty().to_string(), - reference.author().as_str().to_string(), + reference.author().to_hex(), ] } @@ -102,16 +91,16 @@ fn parent_reference_tag(reference: &RadrootsNip22CommentParentReference) -> Vec< "e".to_string(), reference.event_id().as_str().to_string(), reference.relay_or_empty().to_string(), - reference.author().as_str().to_string(), + reference.author().to_hex(), ] } fn participant_tag( name: &str, - author: &str, + author: &PublicKey, relay: Option<&RadrootsNostrRelayHint>, ) -> Vec<String> { - optional_relay_tag(name, author, relay) + optional_relay_tag(name, &author.to_hex(), relay) } fn optional_relay_tag( @@ -138,27 +127,22 @@ mod tests { kinds::{KIND_CALENDAR_DATE_EVENT, KIND_CALENDAR_TIME_EVENT, KIND_CLASSIFIED_LISTING}, }; + fn h(character: char) -> String { + crate::test_fixtures::fixture_public_key_hex(character) + } + fn event_root(relay: Option<&str>) -> RadrootsNip22EventRootReference { - RadrootsNip22EventRootReference::parse( - "a".repeat(64), - "b".repeat(64), - KIND_CLASSIFIED_LISTING, - relay, - ) - .expect("event root") + RadrootsNip22EventRootReference::parse(h('a'), h('b'), KIND_CLASSIFIED_LISTING, relay) + .expect("event root") } fn address_root(relay: Option<&str>) -> RadrootsNip22AddressRootReference { - RadrootsNip22AddressRootReference::parse( - format!("31922:{}:market-day", "b".repeat(64)), - relay, - ) - .expect("address root") + RadrootsNip22AddressRootReference::parse(format!("31922:{}:market-day", h('b')), relay) + .expect("address root") } fn parent(relay: Option<&str>) -> RadrootsNip22CommentParentReference { - RadrootsNip22CommentParentReference::parse("c".repeat(64), "d".repeat(64), relay) - .expect("parent") + RadrootsNip22CommentParentReference::parse(h('c'), h('d'), relay).expect("parent") } #[derive(Clone, Copy)] @@ -180,7 +164,7 @@ mod tests { AuthoredShape::TopAddress => RadrootsAuthoredNip22Comment::parse_top_level_address( content, address_root(None), - "e".repeat(64), + h('e'), ), AuthoredShape::NestedEvent => { RadrootsAuthoredNip22Comment::nested(content, event_root(None), parent(None)) @@ -198,22 +182,12 @@ mod tests { assert_eq!( authored_nip22_comment_to_wire_parts(&comment).tags, vec![ - vec![ - "E".to_string(), - "a".repeat(64), - String::new(), - "b".repeat(64), - ], + vec!["E".to_string(), h('a'), String::new(), h('b'),], vec!["K".to_string(), KIND_CLASSIFIED_LISTING.to_string()], - vec!["P".to_string(), "b".repeat(64)], - vec![ - "e".to_string(), - "a".repeat(64), - String::new(), - "b".repeat(64), - ], + vec!["P".to_string(), h('b')], + vec!["e".to_string(), h('a'), String::new(), h('b'),], vec!["k".to_string(), KIND_CLASSIFIED_LISTING.to_string()], - vec!["p".to_string(), "b".repeat(64)], + vec!["p".to_string(), h('b')], ] ); } @@ -223,7 +197,7 @@ mod tests { let comment = RadrootsAuthoredNip22Comment::parse_top_level_address( "Comment", address_root(Some("wss://relay.example")), - "e".repeat(64), + h('e'), ) .expect("comment"); let tags = authored_nip22_comment_to_wire_parts(&comment).tags; @@ -234,11 +208,7 @@ mod tests { ); assert_eq!( tags[4], - vec![ - "e".to_string(), - "e".repeat(64), - "wss://relay.example".to_string() - ] + vec!["e".to_string(), h('e'), "wss://relay.example".to_string()] ); } @@ -247,8 +217,8 @@ mod tests { for root in [ RadrootsNip22CommentRoot::from( RadrootsNip22EventRootReference::parse( - "a".repeat(64), - "b".repeat(64), + h('a'), + h('b'), KIND_CALENDAR_TIME_EVENT, Some("wss://root.example"), ) @@ -256,7 +226,7 @@ mod tests { ), RadrootsNip22CommentRoot::from( RadrootsNip22AddressRootReference::parse( - format!("31922:{}:market", "b".repeat(64)), + format!("31922:{}:market", h('b')), Some("wss://root.example"), ) .expect("address root"), @@ -273,11 +243,7 @@ mod tests { assert_eq!(tags[4], vec!["k".to_string(), KIND_COMMENT.to_string()]); assert_eq!( tags[5], - vec![ - "p".to_string(), - "d".repeat(64), - "wss://parent.example".to_string() - ] + vec!["p".to_string(), h('d'), "wss://parent.example".to_string()] ); } diff --git a/crates/event_codec/src/comment/inbound/registry_v7.rs b/crates/event_codec/src/comment/inbound/registry_v7.rs @@ -13,11 +13,12 @@ use radroots_event::{ }, ids::{ RadrootsAddressableCoordinate, RadrootsAddressableCoordinateParts, RadrootsEventId, - RadrootsIdParseError, RadrootsPublicKey, + RadrootsIdParseError, }, kinds::KIND_COMMENT, relay_hint::RadrootsNostrRelayHint, }; +use radroots_identity::PublicKey; use crate::verification::v1::RadrootsSignatureVerifiedEvent; @@ -127,7 +128,7 @@ impl RadrootsNip22CommentDiagnostic { #[derive(Clone, Debug, PartialEq, Eq)] pub struct RadrootsInboundNip22Participant { tag_index: usize, - pubkey: RadrootsPublicKey, + pubkey: PublicKey, relay: Option<RadrootsNostrRelayHint>, raw_tag: Vec<String>, } @@ -137,7 +138,7 @@ impl RadrootsInboundNip22Participant { self.tag_index } - pub const fn pubkey(&self) -> &RadrootsPublicKey { + pub const fn pubkey(&self) -> &PublicKey { &self.pubkey } @@ -158,7 +159,7 @@ pub struct RadrootsInboundNip22EventRoot { kind_raw_tag: Vec<String>, kind: RadrootsNip22CommentRootKind, relay: Option<RadrootsNostrRelayHint>, - author_hint: Option<RadrootsPublicKey>, + author_hint: Option<PublicKey>, author: RadrootsInboundNip22Participant, raw_tag: Vec<String>, } @@ -188,7 +189,7 @@ impl RadrootsInboundNip22EventRoot { self.relay.as_ref() } - pub const fn author_hint(&self) -> Option<&RadrootsPublicKey> { + pub const fn author_hint(&self) -> Option<&PublicKey> { self.author_hint.as_ref() } @@ -277,7 +278,7 @@ pub struct RadrootsInboundNip22CommentParent { kind_raw_tag: Vec<String>, kind: u32, relay: Option<RadrootsNostrRelayHint>, - author_hint: Option<RadrootsPublicKey>, + author_hint: Option<PublicKey>, author: RadrootsInboundNip22Participant, raw_tag: Vec<String>, } @@ -307,7 +308,7 @@ impl RadrootsInboundNip22CommentParent { self.relay.as_ref() } - pub const fn author_hint(&self) -> Option<&RadrootsPublicKey> { + pub const fn author_hint(&self) -> Option<&PublicKey> { self.author_hint.as_ref() } @@ -354,7 +355,7 @@ pub struct RadrootsInboundNip22TopLevelEventReference { kind_raw_tag: Vec<String>, kind: u32, relay: Option<RadrootsNostrRelayHint>, - author_hint: Option<RadrootsPublicKey>, + author_hint: Option<PublicKey>, author: RadrootsInboundNip22Participant, raw_tag: Vec<String>, } @@ -430,7 +431,7 @@ impl RadrootsInboundNip22TopLevelEventReference { self.relay.as_ref() } - pub const fn author_hint(&self) -> Option<&RadrootsPublicKey> { + pub const fn author_hint(&self) -> Option<&PublicKey> { self.author_hint.as_ref() } @@ -1092,12 +1093,12 @@ type IndexedTag<'a> = (usize, &'a Vec<String>); struct ParsedEventReference { event_id: RadrootsEventId, relay: Option<RadrootsNostrRelayHint>, - author_hint: Option<RadrootsPublicKey>, + author_hint: Option<PublicKey>, } struct ParsedAddressReference { coordinate: RadrootsAddressableCoordinate, - author: RadrootsPublicKey, + author: PublicKey, kind: RadrootsNip22CommentRootKind, relay: Option<RadrootsNostrRelayHint>, } @@ -1255,7 +1256,7 @@ fn parse_required_root_author( if !matches!(tag.len(), 2 | 3) { return Err(RadrootsNip22CommentProjectionError::RootAuthorInvalid { tag_index }); } - let pubkey = RadrootsPublicKey::parse(&tag[1]) + let pubkey = PublicKey::from_hex(&tag[1]) .map_err(|_| RadrootsNip22CommentProjectionError::RootAuthorInvalid { tag_index })?; let relay = project_relay(tag_index, tag, 2, RelayRole::RootAuthor, diagnostics); Ok(RadrootsInboundNip22Participant { @@ -1279,7 +1280,7 @@ fn project_participants( }); continue; } - let Ok(pubkey) = RadrootsPublicKey::parse(&tag[1]) else { + let Ok(pubkey) = PublicKey::from_hex(&tag[1]) else { diagnostics.push(RadrootsNip22CommentDiagnostic::ParentAuthorInvalidIgnored { tag_index, raw_tag: tag.clone(), @@ -1322,7 +1323,7 @@ fn parse_event_reference( let relay = project_relay(tag_index, tag, 2, role.relay_role(), diagnostics); let author_hint = tag .get(3) - .and_then(|value| match RadrootsPublicKey::parse(value) { + .and_then(|value| match PublicKey::from_hex(value) { Ok(author) => Some(author), Err(_) => { diagnostics.push(role.author_hint_diagnostic(tag_index, tag.clone())); @@ -1407,8 +1408,8 @@ fn require_parent_cardinality( fn select_direct_parent_author( mut participants: Vec<RadrootsInboundNip22Participant>, - expected_author: &RadrootsPublicKey, - author_hint: Option<&RadrootsPublicKey>, + expected_author: &PublicKey, + author_hint: Option<&PublicKey>, ) -> Result< ( RadrootsInboundNip22Participant, @@ -1434,7 +1435,7 @@ fn select_direct_parent_author( fn select_nested_parent_author( mut participants: Vec<RadrootsInboundNip22Participant>, - author_hint: Option<&RadrootsPublicKey>, + author_hint: Option<&PublicKey>, ) -> Result< ( RadrootsInboundNip22Participant, diff --git a/crates/event_codec/src/comment/inbound/registry_v7/tests.rs b/crates/event_codec/src/comment/inbound/registry_v7/tests.rs @@ -1,7 +1,7 @@ use super::*; fn h(character: char) -> String { - character.to_string().repeat(64) + crate::test_fixtures::fixture_public_key_hex(character) } fn top_event_tags() -> Vec<Vec<String>> { @@ -111,9 +111,9 @@ fn nested_parent_uses_author_hint_and_keeps_mentions() { panic!("nested"); }; assert_eq!(parent.event_id().as_str(), h('c')); - assert_eq!(parent.author().pubkey().as_str(), h('d')); + assert_eq!(parent.author().pubkey().to_hex(), h('d')); assert_eq!(projection.mentions().len(), 1); - assert_eq!(projection.mentions()[0].pubkey().as_str(), h('e')); + assert_eq!(projection.mentions()[0].pubkey().to_hex(), h('e')); } #[test] diff --git a/crates/event_codec/src/deletion/authored.rs b/crates/event_codec/src/deletion/authored.rs @@ -54,26 +54,23 @@ mod tests { RadrootsNip09DeletionEventTarget, }; + fn h(character: char) -> String { + crate::test_fixtures::fixture_public_key_hex(character) + } + #[test] fn emits_exact_canonical_two_element_target_and_kind_tags() { let request = RadrootsAuthoredNip09DeletionRequest::new( "superseded", vec![ - RadrootsNip09DeletionEventTarget::parse("f".repeat(64), 30_402) - .expect("event target"), - RadrootsNip09DeletionEventTarget::parse("a".repeat(64), 1).expect("event target"), + RadrootsNip09DeletionEventTarget::parse(h('f'), 30_402).expect("event target"), + RadrootsNip09DeletionEventTarget::parse(h('a'), 1).expect("event target"), ], vec![ - RadrootsNip09DeletionAddressTarget::parse(format!( - "31923:{}:market", - "e".repeat(64) - )) - .expect("address target"), - RadrootsNip09DeletionAddressTarget::parse(format!( - "30402:{}:produce", - "b".repeat(64) - )) - .expect("address target"), + RadrootsNip09DeletionAddressTarget::parse(format!("31923:{}:market", h('e'))) + .expect("address target"), + RadrootsNip09DeletionAddressTarget::parse(format!("30402:{}:produce", h('b'))) + .expect("address target"), ], ) .expect("deletion request"); @@ -84,10 +81,10 @@ mod tests { assert_eq!( parts.tags, vec![ - vec!["e".to_string(), "a".repeat(64)], - vec!["e".to_string(), "f".repeat(64)], - vec!["a".to_string(), format!("30402:{}:produce", "b".repeat(64))], - vec!["a".to_string(), format!("31923:{}:market", "e".repeat(64))], + vec!["e".to_string(), h('a')], + vec!["e".to_string(), h('f')], + vec!["a".to_string(), format!("30402:{}:produce", h('b'))], + vec!["a".to_string(), format!("31923:{}:market", h('e'))], vec!["k".to_string(), "1".to_string()], vec!["k".to_string(), "30402".to_string()], vec!["k".to_string(), "31923".to_string()], @@ -98,8 +95,7 @@ mod tests { #[test] fn core_wire_estimator_matches_emitted_json_at_the_strict_boundary() { - let target = - RadrootsNip09DeletionEventTarget::parse("a".repeat(64), 1).expect("event target"); + let target = RadrootsNip09DeletionEventTarget::parse(h('a'), 1).expect("event target"); let mut lower = 0usize; let mut upper = radroots_event::deletion::RADROOTS_NIP09_DELETION_CONTENT_MAX_BYTES; while lower < upper { @@ -142,11 +138,11 @@ mod tests { fn strict_wire_size_equals_independent_max_u64_serialization_with_escaping() { let request = RadrootsAuthoredNip09DeletionRequest::new( "reason \"quoted\" \\\n\u{0001} 🌱", - vec![RadrootsNip09DeletionEventTarget::parse("A".repeat(64), 5).expect("event target")], + vec![RadrootsNip09DeletionEventTarget::parse(h('A'), 5).expect("event target")], vec![ RadrootsNip09DeletionAddressTarget::parse(format!( "30000:{}:victoria:\"crop\\row:\u{0002}:雪", - "B".repeat(64) + h('B') )) .expect("address target"), ], diff --git a/crates/event_codec/src/deletion/reconciliation_v1.rs b/crates/event_codec/src/deletion/reconciliation_v1.rs @@ -400,8 +400,7 @@ pub mod evaluator { } else { return None; }; - RadrootsNip01Coordinate::parse(format!("{kind}:{}:{identifier}", event.author().as_str())) - .ok() + RadrootsNip01Coordinate::parse(format!("{kind}:{}:{identifier}", event.author())).ok() } const fn decision( diff --git a/crates/event_codec/src/deletion/reconciliation_v1/evaluator/tests.rs b/crates/event_codec/src/deletion/reconciliation_v1/evaluator/tests.rs @@ -495,7 +495,7 @@ fn coordinate_for( RadrootsNip01Coordinate::parse(format!( "{}:{}:{identifier}", target.event().kind_u32(), - target.event().author_str() + target.event().author().to_hex() )) .expect("target coordinate") } diff --git a/crates/event_codec/src/deletion/reconciliation_v1/inbound/tests.rs b/crates/event_codec/src/deletion/reconciliation_v1/inbound/tests.rs @@ -1,7 +1,7 @@ use super::*; fn h(character: char) -> String { - character.to_string().repeat(64) + crate::test_fixtures::fixture_public_key_hex(character) } fn valid_event_tags() -> Vec<Vec<String>> { diff --git a/crates/event_codec/src/event_ref.rs b/crates/event_codec/src/event_ref.rs @@ -7,8 +7,9 @@ use alloc::{ use radroots_event::{ RadrootsEventRef, - ids::{RadrootsDTag, RadrootsEventId, RadrootsPublicKey, RadrootsRelayUrl}, + ids::{RadrootsDTag, RadrootsEventId, RadrootsRelayUrl}, }; +use radroots_identity::PublicKey; use crate::error::EventParseError; @@ -39,7 +40,7 @@ pub fn parse_event_ref_tag( let id = &tag[1]; RadrootsEventId::parse(id).map_err(|_| EventParseError::InvalidTag(tag_name))?; let author = &tag[2]; - RadrootsPublicKey::parse(author).map_err(|_| EventParseError::InvalidTag(tag_name))?; + PublicKey::from_hex(author).map_err(|_| EventParseError::InvalidTag(tag_name))?; let kind_s = &tag[3]; let kind: u32 = kind_s .parse() diff --git a/crates/event_codec/src/farm/mod.rs b/crates/event_codec/src/farm/mod.rs @@ -28,7 +28,7 @@ mod tests { #[cfg(feature = "serde_json")] const EVENT_ID: &str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; #[cfg(feature = "serde_json")] - const AUTHOR: &str = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; + const AUTHOR: &str = crate::test_fixtures::FIXTURE_ALICE_PUBLIC_KEY_HEX; #[cfg(feature = "serde_json")] const EVENT_SIG: &str = concat!( "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", diff --git a/crates/event_codec/src/farm_crdt/mod.rs b/crates/event_codec/src/farm_crdt/mod.rs @@ -29,7 +29,7 @@ mod tests { const DOCUMENT_ID: &str = "AAAAAAAAAAAAAAAAAAAAAg"; const GROUP_ID: &str = "field-group"; const EVENT_ID: &str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; - const AUTHOR: &str = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; + const AUTHOR: &str = crate::test_fixtures::FIXTURE_ALICE_PUBLIC_KEY_HEX; const EVENT_SIG: &str = concat!( "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" diff --git a/crates/event_codec/src/farm_file/mod.rs b/crates/event_codec/src/farm_file/mod.rs @@ -26,7 +26,7 @@ mod tests { const OWNER_DOCUMENT_ID: &str = "AAAAAAAAAAAAAAAAAAAAAg"; const GROUP_ID: &str = "field-group"; const EVENT_ID: &str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; - const AUTHOR: &str = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; + const AUTHOR: &str = crate::test_fixtures::FIXTURE_ALICE_PUBLIC_KEY_HEX; const EVENT_SIG: &str = concat!( "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" diff --git a/crates/event_codec/src/farm_workspace/mod.rs b/crates/event_codec/src/farm_workspace/mod.rs @@ -29,7 +29,7 @@ mod tests { const FARM_D_TAG: &str = "AAAAAAAAAAAAAAAAAAAAAQ"; const GROUP_ID: &str = "field-group"; const EVENT_ID: &str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; - const AUTHOR: &str = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; + const AUTHOR: &str = crate::test_fixtures::FIXTURE_ALICE_PUBLIC_KEY_HEX; const EVENT_SIG: &str = concat!( "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" diff --git a/crates/event_codec/src/food_availability/revision.rs b/crates/event_codec/src/food_availability/revision.rs @@ -82,7 +82,7 @@ pub fn validate_food_availability_revision( let current_event = current.event(); if previous_event.kind_u32() != current_event.kind_u32() - || previous_event.author_str() != current_event.author_str() + || previous_event.author().to_hex() != current_event.author().to_hex() || previous_projection.identifier() != current_projection.identifier() { return Err(RadrootsFoodAvailabilityRevisionError::CoordinateChanged); diff --git a/crates/event_codec/src/http_auth/mod.rs b/crates/event_codec/src/http_auth/mod.rs @@ -10,7 +10,7 @@ mod tests { use crate::http_auth::encode::{http_auth_build_tags, to_wire_parts, to_wire_parts_with_kind}; const EVENT_ID: &str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; - const AUTHOR: &str = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; + const AUTHOR: &str = crate::test_fixtures::FIXTURE_ALICE_PUBLIC_KEY_HEX; const EVENT_SIG: &str = concat!( "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" diff --git a/crates/event_codec/src/job/traits.rs b/crates/event_codec/src/job/traits.rs @@ -116,7 +116,7 @@ pub trait JobEventLike { pub trait JobEventBorrow<'a> { fn raw_id(&'a self) -> &'a str; - fn raw_author(&'a self) -> &'a str; + fn raw_author(&'a self) -> String; fn raw_content(&'a self) -> &'a str; fn raw_kind(&'a self) -> u32; } @@ -147,7 +147,7 @@ impl<'a, E: JobEventBorrow<'a>> JobEventLike for BorrowedEventAdapter<'a, E> { } #[inline] fn raw_author(&self) -> String { - self.inner.raw_author().to_owned() + self.inner.raw_author() } #[inline] fn raw_published_at(&self) -> u64 { @@ -177,8 +177,8 @@ impl<'a> JobEventBorrow<'a> for radroots_event::RadrootsEventEnvelope { self.id_str() } #[inline] - fn raw_author(&'a self) -> &'a str { - self.author_str() + fn raw_author(&'a self) -> String { + self.author().to_hex() } #[inline] fn raw_content(&'a self) -> &'a str { diff --git a/crates/event_codec/src/knowledge/decode.rs b/crates/event_codec/src/knowledge/decode.rs @@ -378,7 +378,7 @@ fn json_content<T: DeserializeOwned>(content: &str) -> Result<T, EventParseError fn parsed<T>(event: RadrootsEventEnvelope, data: T) -> RadrootsParsedEvent<T> { let parsed_data = RadrootsParsedData::new( event.id_str().to_string(), - event.author_str().to_string(), + event.author().to_hex().to_string(), event.created_at_u64(), event.kind_u32(), data, diff --git a/crates/event_codec/src/operational_listing/decode.rs b/crates/event_codec/src/operational_listing/decode.rs @@ -747,7 +747,7 @@ pub fn data_from_nostr_event( ) -> Result<RadrootsParsedData<RadrootsOperationalListing>, EventParseError> { data_from_event( event.id_str().to_string(), - event.author_str().to_string(), + event.author().to_hex().to_string(), event.created_at_u64(), event.kind_u32(), event.content().to_string(), @@ -760,7 +760,7 @@ pub fn parsed_from_nostr_event( ) -> Result<RadrootsParsedEvent<RadrootsOperationalListing>, EventParseError> { parsed_from_event( event.id_str().to_string(), - event.author_str().to_string(), + event.author().to_hex().to_string(), event.created_at_u64(), event.kind_u32(), event.content().to_string(), diff --git a/crates/event_codec/src/order/decode.rs b/crates/event_codec/src/order/decode.rs @@ -4,9 +4,7 @@ use alloc::{string::String, vec::Vec}; #[cfg(feature = "serde_json")] use radroots_event::{ RadrootsEventEnvelope, RadrootsEventPtr, - ids::{ - RadrootsClassifiedListingAddress, RadrootsEventId, RadrootsIdParseError, RadrootsPublicKey, - }, + ids::{RadrootsClassifiedListingAddress, RadrootsEventId, RadrootsIdParseError}, kinds::is_order_event_kind, order::{ RadrootsOrderCancellation, RadrootsOrderDecision, RadrootsOrderEnvelope, @@ -16,6 +14,8 @@ use radroots_event::{ tags::{TAG_D, TAG_E_PREV, TAG_E_ROOT}, }; #[cfg(feature = "serde_json")] +use radroots_identity::PublicKey; +#[cfg(feature = "serde_json")] use serde::de::DeserializeOwned; #[cfg(feature = "serde_json")] @@ -95,7 +95,7 @@ impl std::error::Error for RadrootsOrderEnvelopeParseError { #[cfg(feature = "serde_json")] #[derive(Clone, Debug, PartialEq, Eq)] pub struct RadrootsOrderEventContext { - pub counterparty_pubkey: RadrootsPublicKey, + pub counterparty_pubkey: PublicKey, pub listing_event: Option<RadrootsEventPtr>, pub root_event_id: Option<RadrootsEventId>, pub prev_event_id: Option<RadrootsEventId>, @@ -223,7 +223,7 @@ pub fn order_event_context_from_tags( ) -> Result<RadrootsOrderEventContext, RadrootsOrderEnvelopeParseError> { let counterparty_pubkey = parse_order_counterparty_tag(tags).map_err(map_tag_parse_error_for_order_envelope)?; - let counterparty_pubkey = RadrootsPublicKey::parse(&counterparty_pubkey) + let counterparty_pubkey = PublicKey::from_hex(&counterparty_pubkey) .map_err(|_| RadrootsOrderEnvelopeParseError::InvalidTag("p"))?; let listing_event = parse_order_listing_event_tag(tags).map_err(map_tag_parse_error_for_order_envelope)?; @@ -316,8 +316,8 @@ fn validate_order_binding<T>( envelope: &RadrootsOrderEnvelope<T>, payload_order_id: &str, payload_listing_addr: &str, - expected_author: &str, - expected_counterparty: &str, + expected_author: &PublicKey, + expected_counterparty: &PublicKey, ) -> Result<(), RadrootsOrderEnvelopeParseError> { if envelope.order_id != payload_order_id { return Err(RadrootsOrderEnvelopeParseError::PayloadBindingMismatch( @@ -329,11 +329,11 @@ fn validate_order_binding<T>( "listing_addr", )); } - if event.author_str() != expected_author { + if event.author() != expected_author { return Err(RadrootsOrderEnvelopeParseError::AuthorMismatch); } let context = order_event_context_from_tags(envelope.message_type, &event.tags_as_vec())?; - if context.counterparty_pubkey.as_str() != expected_counterparty { + if &context.counterparty_pubkey != expected_counterparty { return Err(RadrootsOrderEnvelopeParseError::CounterpartyTagMismatch); } Ok(()) @@ -355,7 +355,7 @@ mod tests { RadrootsEventEnvelope, RadrootsEventEnvelopeParts, RadrootsEventPtr, ids::{ RadrootsClassifiedListingAddress, RadrootsEventId, RadrootsInventoryBinId, - RadrootsOrderId, RadrootsOrderQuoteId, RadrootsPublicKey, + RadrootsOrderId, RadrootsOrderQuoteId, }, kinds::{KIND_ORDER_CANCELLATION, KIND_ORDER_DECISION, KIND_ORDER_REQUEST}, order::{ @@ -367,28 +367,28 @@ mod tests { }, tags::{TAG_D, TAG_E_PREV, TAG_E_ROOT}, }; + use radroots_identity::PublicKey; - fn pubkey(character: char) -> RadrootsPublicKey { - core::iter::repeat_n(character, 64) - .collect::<String>() + fn pubkey(character: char) -> PublicKey { + crate::test_fixtures::fixture_public_key_hex(character) .parse() .unwrap() } - fn buyer_pubkey() -> RadrootsPublicKey { + fn buyer_pubkey() -> PublicKey { pubkey('b') } - fn seller_pubkey() -> RadrootsPublicKey { + fn seller_pubkey() -> PublicKey { pubkey('a') } fn buyer_pubkey_wire() -> String { - buyer_pubkey().into_string() + buyer_pubkey().to_hex() } fn seller_pubkey_wire() -> String { - seller_pubkey().into_string() + seller_pubkey().to_hex() } fn listing_addr() -> RadrootsClassifiedListingAddress { @@ -1138,7 +1138,7 @@ mod tests { assert_eq!(err, RadrootsOrderEnvelopeParseError::AuthorMismatch); let mut tags = built.tags; - tags[0] = vec!["p".into(), pubkey('c').into_string()]; + tags[0] = vec!["p".into(), pubkey('c').to_hex()]; let counterparty_mismatch = event_envelope(buyer_pubkey_wire(), built.kind, tags, built.content); let err = order_request_from_event(&counterparty_mismatch).unwrap_err(); diff --git a/crates/event_codec/src/order/encode.rs b/crates/event_codec/src/order/encode.rs @@ -13,6 +13,8 @@ use radroots_event::{ use crate::{error::EventEncodeError, order::tags::order_envelope_tags}; #[cfg(feature = "serde_json")] use radroots_event::wire::RadrootsNip01EventWireParts; +#[cfg(feature = "serde_json")] +use radroots_identity::PublicKey; #[cfg(feature = "serde_json")] fn map_order_envelope_error(error: RadrootsOrderEnvelopeError) -> EventEncodeError { @@ -75,7 +77,7 @@ fn map_order_payload_error(error: RadrootsOrderPayloadError) -> EventEncodeError #[cfg(feature = "serde_json")] struct OrderEnvelopeEventBuildParts<'a, T> { - recipient_pubkey: &'a str, + recipient_pubkey: &'a PublicKey, message_type: RadrootsOrderEventType, listing_addr: &'a str, order_id: &'a str, @@ -110,7 +112,7 @@ fn order_envelope_event_build<T: serde::Serialize>( envelope.validate().map_err(map_order_envelope_error)?; let content = serde_json::to_string(&envelope).map_err(|_| EventEncodeError::Json)?; let tags = order_envelope_tags( - parts.recipient_pubkey, + &parts.recipient_pubkey.to_hex(), parts.listing_addr, Some(parts.order_id), parts.listing_event, @@ -192,6 +194,9 @@ mod tests { ids::RadrootsEventId, order::{RadrootsOrderEnvelopeError, RadrootsOrderEventType, RadrootsOrderPayloadError}, }; + use radroots_identity::PublicKey; + + const RECIPIENT: &str = "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df"; fn event_id(character: char) -> RadrootsEventId { core::iter::repeat_n(character, 64) @@ -307,11 +312,12 @@ mod tests { #[test] fn order_envelope_event_build_requires_context_tags_by_message_type() { let payload = payload(); + let recipient_pubkey = PublicKey::from_hex(RECIPIENT).expect("recipient public key"); let root_event_id = event_id('1'); let prev_event_id = event_id('2'); let missing_listing_event = order_envelope_event_build(OrderEnvelopeEventBuildParts { - recipient_pubkey: "recipient", + recipient_pubkey: &recipient_pubkey, message_type: RadrootsOrderEventType::OrderRequested, listing_addr: "listing-address", order_id: "order-1", @@ -324,7 +330,7 @@ mod tests { assert_empty_required(missing_listing_event, "listing_event.id"); let missing_root = order_envelope_event_build(OrderEnvelopeEventBuildParts { - recipient_pubkey: "recipient", + recipient_pubkey: &recipient_pubkey, message_type: RadrootsOrderEventType::OrderDecision, listing_addr: "listing-address", order_id: "order-1", @@ -337,7 +343,7 @@ mod tests { assert_empty_required(missing_root, "root_event_id"); let missing_prev = order_envelope_event_build(OrderEnvelopeEventBuildParts { - recipient_pubkey: "recipient", + recipient_pubkey: &recipient_pubkey, message_type: RadrootsOrderEventType::OrderDecision, listing_addr: "listing-address", order_id: "order-1", @@ -350,7 +356,7 @@ mod tests { assert_empty_required(missing_prev, "prev_event_id"); let invalid_listing_event = order_envelope_event_build(OrderEnvelopeEventBuildParts { - recipient_pubkey: "recipient", + recipient_pubkey: &recipient_pubkey, message_type: RadrootsOrderEventType::OrderRequested, listing_addr: "listing-address", order_id: "order-1", diff --git a/crates/event_codec/src/parsed.rs b/crates/event_codec/src/parsed.rs @@ -95,7 +95,7 @@ mod tests { use radroots_event::{RadrootsEventEnvelope, RadrootsEventEnvelopeParts}; const EVENT_ID: &str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; - const AUTHOR: &str = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; + const AUTHOR: &str = crate::test_fixtures::FIXTURE_ALICE_PUBLIC_KEY_HEX; const SIG: &str = concat!( "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" @@ -162,7 +162,7 @@ mod tests { ) .unwrap(); assert_eq!(out.event.id_str(), EVENT_ID); - assert_eq!(out.event.author_str(), AUTHOR); + assert_eq!(out.event.author().to_hex(), AUTHOR); assert_eq!(out.event.created_at_u64(), 77); assert_eq!(out.event.kind_u32(), 1111); assert_eq!(out.event.content(), "hello"); diff --git a/crates/event_codec/src/relay_auth/mod.rs b/crates/event_codec/src/relay_auth/mod.rs @@ -12,7 +12,7 @@ mod tests { }; const EVENT_ID: &str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; - const AUTHOR: &str = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; + const AUTHOR: &str = crate::test_fixtures::FIXTURE_ALICE_PUBLIC_KEY_HEX; const EVENT_SIG: &str = concat!( "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" diff --git a/crates/event_codec/src/reply/authored.rs b/crates/event_codec/src/reply/authored.rs @@ -45,38 +45,32 @@ fn event_tag(reference: &RadrootsNip10ReplyReference, marker: &str) -> Vec<Strin } fn public_key_tag(reference: &RadrootsNip10ReplyReference) -> Vec<String> { - vec!["p".to_string(), reference.author().as_str().to_string()] + vec!["p".to_string(), reference.author().to_hex()] } #[cfg(test)] mod tests { use super::*; + fn h(character: char) -> String { + crate::test_fixtures::fixture_public_key_hex(character) + } + #[test] fn nested_reply_deduplicates_equal_reference_authors() { - let author = "b".repeat(64); - let root = RadrootsNip10ReplyReference::parse("a".repeat(64), &author, None) - .expect("root reference"); - let parent = RadrootsNip10ReplyReference::parse("c".repeat(64), &author, None) - .expect("parent reference"); + let author = h('b'); + let root = + RadrootsNip10ReplyReference::parse(h('a'), &author, None).expect("root reference"); + let parent = + RadrootsNip10ReplyReference::parse(h('c'), &author, None).expect("parent reference"); let reply = RadrootsAuthoredNip10Reply::nested("Reply", root, parent).expect("nested reply"); assert_eq!( authored_nip10_reply_to_wire_parts(&reply).tags, vec![ - vec![ - "e".to_string(), - "a".repeat(64), - String::new(), - "root".to_string(), - ], - vec![ - "e".to_string(), - "c".repeat(64), - String::new(), - "reply".to_string(), - ], + vec!["e".to_string(), h('a'), String::new(), "root".to_string(),], + vec!["e".to_string(), h('c'), String::new(), "reply".to_string(),], vec!["p".to_string(), author], ] ); diff --git a/crates/event_codec/src/reply/inbound/registry_v7.rs b/crates/event_codec/src/reply/inbound/registry_v7.rs @@ -7,7 +7,7 @@ use core::fmt; use std::collections::BTreeSet; use radroots_event::{ - ids::{RadrootsEventId, RadrootsIdParseError, RadrootsPublicKey}, + ids::{RadrootsEventId, RadrootsIdParseError}, kinds::KIND_POST, post::{ RADROOTS_POST_CONTENT_MAX_BYTES, RADROOTS_POST_EVENT_WIRE_MAX_BYTES, @@ -15,6 +15,7 @@ use radroots_event::{ }, relay_hint::RadrootsNostrRelayHint, }; +use radroots_identity::{Error as PublicKeyError, PublicKey}; use crate::verification::v1::RadrootsSignatureVerifiedEvent; @@ -54,7 +55,7 @@ pub enum RadrootsNip10ReplyDiagnostic { ReferenceAuthorIgnored { tag_index: usize, raw_tag: Vec<String>, - error: RadrootsIdParseError, + error: PublicKeyError, }, CitationShapeIgnored { tag_index: usize, @@ -76,7 +77,7 @@ pub enum RadrootsNip10ReplyDiagnostic { ReplyAuthorIgnored { tag_index: usize, raw_tag: Vec<String>, - error: RadrootsIdParseError, + error: PublicKeyError, }, ReplyAuthorRelayIgnored { tag_index: usize, @@ -149,7 +150,7 @@ pub struct RadrootsInboundNip10EventReference { raw_tag: Vec<String>, event_id: RadrootsEventId, relay: Option<RadrootsNostrRelayHint>, - author_hint: Option<RadrootsPublicKey>, + author_hint: Option<PublicKey>, } impl RadrootsInboundNip10EventReference { @@ -169,7 +170,7 @@ impl RadrootsInboundNip10EventReference { self.relay.as_ref() } - pub const fn author_hint(&self) -> Option<&RadrootsPublicKey> { + pub const fn author_hint(&self) -> Option<&PublicKey> { self.author_hint.as_ref() } } @@ -178,7 +179,7 @@ impl RadrootsInboundNip10EventReference { pub struct RadrootsInboundNip10Participant { tag_index: usize, raw_tag: Vec<String>, - pubkey: RadrootsPublicKey, + pubkey: PublicKey, relay: Option<RadrootsNostrRelayHint>, } @@ -191,7 +192,7 @@ impl RadrootsInboundNip10Participant { &self.raw_tag } - pub const fn pubkey(&self) -> &RadrootsPublicKey { + pub const fn pubkey(&self) -> &PublicKey { &self.pubkey } @@ -575,7 +576,7 @@ fn parse_event_reference( } }; let author_hint = if tag.len() == 5 { - match RadrootsPublicKey::parse(&tag[4]) { + match PublicKey::from_hex(&tag[4]) { Ok(author) => Some(author), Err(error) => { diagnostics.push(RadrootsNip10ReplyDiagnostic::ReferenceAuthorIgnored { @@ -651,7 +652,7 @@ fn project_supplemental_reference( } }; let author_hint = if tag.len() == 5 { - match RadrootsPublicKey::parse(&tag[4]) { + match PublicKey::from_hex(&tag[4]) { Ok(author) => Some(author), Err(error) => { diagnostics.push(RadrootsNip10ReplyDiagnostic::ReferenceAuthorIgnored { @@ -705,7 +706,7 @@ fn project_participants( continue; } } - let pubkey = match RadrootsPublicKey::parse(&tag[1]) { + let pubkey = match PublicKey::from_hex(&tag[1]) { Ok(pubkey) => pubkey, Err(error) => { diagnostics.push(RadrootsNip10ReplyDiagnostic::ReplyAuthorIgnored { diff --git a/crates/event_codec/src/reply/inbound/registry_v7/tests.rs b/crates/event_codec/src/reply/inbound/registry_v7/tests.rs @@ -1,12 +1,16 @@ use super::*; +fn h(character: char) -> String { + crate::test_fixtures::fixture_public_key_hex(character) +} + #[test] fn tolerant_inbound_accepts_blank_content_and_absent_participants() { let projection = project_nip10_reply_parts( KIND_POST, &[vec![ "e".to_string(), - "a".repeat(64), + h('a'), String::new(), "root".to_string(), ]], @@ -31,10 +35,10 @@ fn tolerant_inbound_accepts_blank_content_and_absent_participants() { #[test] fn tolerant_inbound_retains_raw_optional_metadata_and_orders_diagnostics() { - let root_id = "a".repeat(64); - let parent_id = "d".repeat(64); - let participant = "b".repeat(64); - let parent_author_hint = "c".repeat(64); + let root_id = h('a'); + let parent_id = h('d'); + let participant = h('b'); + let parent_author_hint = h('c'); let tags = vec![ vec![ "e".to_string(), @@ -76,7 +80,7 @@ fn tolerant_inbound_retains_raw_optional_metadata_and_orders_diagnostics() { assert_eq!(projection.participants().len(), 1); assert_eq!(projection.participants()[0].tag_index(), 4); assert_eq!(projection.participants()[0].raw_tag(), tags[4]); - assert_eq!(projection.participants()[0].pubkey().as_str(), participant); + assert_eq!(projection.participants()[0].pubkey().to_hex(), participant); assert!(projection.participants()[0].relay().is_none()); assert_eq!( @@ -121,8 +125,8 @@ fn tolerant_inbound_retains_raw_optional_metadata_and_orders_diagnostics() { #[test] fn inbound_projection_uses_the_canonical_relay_hint_profile() { - let root_id = "a".repeat(64); - let root_author = "b".repeat(64); + let root_id = h('a'); + let root_author = h('b'); for relay in [ "wss://%65xample.com", "wss://127.1", @@ -198,8 +202,8 @@ fn inbound_relay_syntax_and_tag_element_budgets_remain_separate() { RadrootsNostrRelayHint::parse(&relay).expect("relay syntax has no Reply wire budget"); let tags = vec![ - vec!["e".to_string(), "a".repeat(64), relay, "root".to_string()], - vec!["p".to_string(), "b".repeat(64)], + vec!["e".to_string(), h('a'), relay, "root".to_string()], + vec!["p".to_string(), h('b')], ]; assert!(matches!( project_nip10_reply_parts(KIND_POST, &tags, "Reply", 10), @@ -214,7 +218,7 @@ fn inbound_relay_syntax_and_tag_element_budgets_remain_separate() { #[test] fn tolerant_inbound_keeps_reference_ids_and_markers_as_hard_gates() { - let author = "b".repeat(64); + let author = h('b'); for (tag, expected) in [ ( vec![ @@ -228,7 +232,7 @@ fn tolerant_inbound_keeps_reference_ids_and_markers_as_hard_gates() { ( vec![ "e".to_string(), - "a".repeat(64), + h('a'), String::new(), "mention".to_string(), ], @@ -248,8 +252,8 @@ fn tolerant_inbound_keeps_reference_ids_and_markers_as_hard_gates() { #[test] fn marked_inbound_retains_citations_and_ignores_malformed_supplements() { - let root_id = "a".repeat(64); - let citation_id = "c".repeat(64); + let root_id = h('a'); + let citation_id = h('c'); let tags = vec![ vec!["e".to_string()], vec![ @@ -257,12 +261,12 @@ fn marked_inbound_retains_citations_and_ignores_malformed_supplements() { citation_id.clone(), "wss://relay.example".to_string(), String::new(), - "b".repeat(64), + h('b'), ], vec!["e".to_string(), "not-an-event-id".to_string()], vec![ "e".to_string(), - "d".repeat(64), + h('d'), String::new(), "mention".to_string(), ], @@ -293,8 +297,8 @@ fn marked_inbound_retains_citations_and_ignores_malformed_supplements() { projection.citations()[0] .author_hint() .expect("citation author") - .as_str(), - "b".repeat(64) + .to_hex(), + h('b') ); assert_eq!( projection @@ -322,8 +326,8 @@ fn marked_inbound_retains_citations_and_ignores_malformed_supplements() { #[test] fn positional_inbound_accepts_empty_markers_and_tolerates_middle_citations() { - let root_id = "a".repeat(64); - let root_author = "b".repeat(64); + let root_id = h('a'); + let root_author = h('b'); let direct_tags = vec![ vec![ "e".to_string(), @@ -343,15 +347,15 @@ fn positional_inbound_accepts_empty_markers_and_tolerates_middle_citations() { .root() .author_hint() .expect("root author hint") - .as_str(), + .to_hex(), root_author ); assert!(direct.diagnostics().is_empty()); - let parent_id = "c".repeat(64); - let parent_author = "d".repeat(64); - let citation_id = "e".repeat(64); - let citation_author = "f".repeat(64); + let parent_id = h('c'); + let parent_author = h('d'); + let citation_id = h('e'); + let citation_author = h('f'); let nested_tags = vec![ vec![ "e".to_string(), diff --git a/crates/event_codec/src/test_fixtures.rs b/crates/event_codec/src/test_fixtures.rs @@ -98,6 +98,23 @@ pub const FIXTURE_DIEGO: ApprovedFixtureIdentity = ApprovedFixtureIdentity { npub: FIXTURE_DIEGO_NPUB, }; +pub fn fixture_public_key_hex(character: char) -> String { + let canonical = match character.to_ascii_lowercase() { + 'a' => FIXTURE_ALICE_PUBLIC_KEY_HEX, + 'b' => FIXTURE_BOB_PUBLIC_KEY_HEX, + 'c' => FIXTURE_CAROL_PUBLIC_KEY_HEX, + 'd' => FIXTURE_DIEGO_PUBLIC_KEY_HEX, + 'e' => "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", + 'f' => "f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9", + _ => panic!("unsupported fixture public-key label: {character}"), + }; + if character.is_ascii_uppercase() { + canonical.to_ascii_uppercase() + } else { + canonical.to_owned() + } +} + pub const RELAY_PRIMARY_WSS: &str = "wss://relay.example.com"; pub const RELAY_SECONDARY_WSS: &str = "wss://relay-2.example.com"; pub const RELAY_TERTIARY_WSS: &str = "wss://relay-3.example.com"; diff --git a/crates/event_codec/src/trade/mod.rs b/crates/event_codec/src/trade/mod.rs @@ -121,7 +121,7 @@ fn validate_trade_mutation_tags( return Err(RadrootsTradeMutationParseError::TradeIdTagMismatch); } let counterparty = required_tag_value(tags, "p")?; - if counterparty != envelope.counterparty_pubkey.as_str() { + if counterparty != envelope.counterparty_pubkey.to_hex() { return Err(RadrootsTradeMutationParseError::CounterpartyTagMismatch); } let mut parents = Vec::new(); @@ -216,7 +216,7 @@ mod tests { RadrootsEventEnvelope, RadrootsEventEnvelopeParts, ids::{ RadrootsClassifiedListingAddress, RadrootsDTag, RadrootsEventId, - RadrootsInventoryBinId, RadrootsPublicKey, RadrootsTradeId, + RadrootsInventoryBinId, RadrootsTradeId, }, trade::{ RADROOTS_TRADE_PROPOSAL_CONTRACT_ID, RADROOTS_TRADE_SCHEMA_VERSION, @@ -226,6 +226,7 @@ mod tests { RadrootsTradeMutationBodyV1, RadrootsTradeMutationEnvelopeV1, }, }; + use radroots_identity::PublicKey; fn hex_64(character: char) -> String { core::iter::repeat_n(character, 64).collect() @@ -235,8 +236,8 @@ mod tests { core::iter::repeat_n(character, 32).collect() } - fn pubkey(character: char) -> RadrootsPublicKey { - RadrootsPublicKey::parse(hex_64(character)).unwrap() + fn pubkey(character: char) -> PublicKey { + PublicKey::from_hex(&crate::test_fixtures::fixture_public_key_hex(character)).unwrap() } fn event_id(character: char) -> RadrootsEventId { @@ -276,7 +277,7 @@ mod tests { line_id: RadrootsDTag::parse("line-1").unwrap(), listing_addr: RadrootsClassifiedListingAddress::parse(format!( "30402:{}:listing-1", - hex_64('b') + pubkey('b').to_hex() )) .unwrap(), listing_event_id: event_id('c'), @@ -340,7 +341,7 @@ mod tests { let envelope = trade_mutation_from_event( &RadrootsEventEnvelope::new(RadrootsEventEnvelopeParts { id: hex_64('e'), - author: hex_64('a'), + author: pubkey('a').to_hex(), created_at: 1_799_000_000, kind: parts.kind, tags: parts.tags, @@ -401,7 +402,7 @@ mod tests { *tags .iter_mut() .find(|tag| tag.first().map(String::as_str) == Some("p")) - .unwrap() = vec!["p".into(), hex_64('c')]; + .unwrap() = vec!["p".into(), pubkey('c').to_hex()]; assert_eq!( validate_trade_mutation_tags(&proposal(), &tags).unwrap_err(), RadrootsTradeMutationParseError::CounterpartyTagMismatch @@ -454,7 +455,7 @@ mod tests { let built = trade_mutation_event_build(proposal()).unwrap(); let invalid_kind = RadrootsEventEnvelope::new(RadrootsEventEnvelopeParts { id: hex_64('e'), - author: hex_64('a'), + author: pubkey('a').to_hex(), created_at: 1_799_000_000, kind: 1, tags: built.tags.clone(), @@ -469,7 +470,7 @@ mod tests { let kind_contract_mismatch = RadrootsEventEnvelope::new(RadrootsEventEnvelopeParts { id: hex_64('e'), - author: hex_64('a'), + author: pubkey('a').to_hex(), created_at: 1_799_000_000, kind: radroots_event::kinds::KIND_TRADE_DECISION, tags: built.tags, diff --git a/crates/event_codec/src/verification/v1.rs b/crates/event_codec/src/verification/v1.rs @@ -142,7 +142,7 @@ pub fn verify_event_id_v1( RadrootsEventId::parse(event.id_str()) .map_err(|_| RadrootsNip01VerificationError::MalformedEnvelope)?; let expected = compute_canonical_nip01_event_id_v1( - event.author_str(), + &event.author().to_hex(), event.created_at_u64(), event.kind_u32(), &event.tags_as_vec(), @@ -232,7 +232,7 @@ fn raw_event_from_radroots( ) -> Result<nostr::Event, RadrootsNip01VerificationError> { let id = nostr::EventId::from_hex(event.id_str()) .map_err(|_| RadrootsNip01VerificationError::MalformedEnvelope)?; - let public_key = nostr::secp256k1::XOnlyPublicKey::from_str(event.author_str()) + let public_key = nostr::secp256k1::XOnlyPublicKey::from_str(&event.author().to_hex()) .map(nostr::PublicKey::from) .map_err(|_| RadrootsNip01VerificationError::MalformedEnvelope)?; let kind = u16::try_from(event.kind_u32()).map_err(|_| { diff --git a/crates/event_codec/src/verification/v1/tests.rs b/crates/event_codec/src/verification/v1/tests.rs @@ -70,7 +70,7 @@ fn id_verification_rejects_an_out_of_range_kind_before_hashing() { let original = signed_max_kind_event(); let kind = u32::from(u16::MAX) + 1; let id = compute_canonical_nip01_event_id_v1( - original.author_str(), + &original.author().to_hex(), original.created_at_u64(), kind, &original.tags_as_vec(), @@ -80,7 +80,7 @@ fn id_verification_rejects_an_out_of_range_kind_before_hashing() { .into_string(); let event = RadrootsEventEnvelope::new(RadrootsEventEnvelopeParts { id, - author: original.author_str().to_owned(), + author: original.author().to_hex().to_owned(), created_at: original.created_at_u64(), kind, tags: original.tags_as_vec(), diff --git a/crates/event_codec/tests/app_data.rs b/crates/event_codec/tests/app_data.rs @@ -132,7 +132,7 @@ fn app_data_metadata_and_index_from_event_roundtrip() { ) .unwrap(); assert_eq!(index.event.id_str(), EVENT_ID); - assert_eq!(index.event.author_str(), AUTHOR); + assert_eq!(index.event.author().to_hex(), AUTHOR); assert_eq!(index.event.created_at_u64(), 42); assert_eq!(index.event.kind_u32(), KIND_APP_DATA); assert_eq!(index.event.content(), "payload"); diff --git a/crates/event_codec/tests/article.rs b/crates/event_codec/tests/article.rs @@ -218,7 +218,7 @@ fn article_wrappers_preserve_event_metadata() { .unwrap(); assert_eq!(parsed.event.id_str(), EVENT_ID); - assert_eq!(parsed.event.author_str(), AUTHOR); + assert_eq!(parsed.event.author().to_hex(), AUTHOR); assert_eq!(parsed.event.sig_str(), EVENT_SIG); assert_eq!(parsed.data.data.d_tag, VALID_D_TAG); } diff --git a/crates/event_codec/tests/calendar.rs b/crates/event_codec/tests/calendar.rs @@ -44,8 +44,8 @@ use radroots_event_codec::{ const DATE_D_TAG: &str = "fernwood-csa-pickup"; const TIME_D_TAG: &str = "wash-pack-shift"; const EVENT_ID: &str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; -const EVENT_AUTHOR: &str = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; -const SECOND_AUTHOR: &str = "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"; +const EVENT_AUTHOR: &str = "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df"; +const SECOND_AUTHOR: &str = "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"; const EVENT_SIG: &str = concat!( "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd" diff --git a/crates/event_codec/tests/calendar_conformance.rs b/crates/event_codec/tests/calendar_conformance.rs @@ -596,7 +596,7 @@ fn assert_author_reference( let relay = expected.get("relay").and_then(Value::as_str); assert_eq!(actual.raw_pubkey(), pubkey, "{}", vector_id(vector)); assert_eq!( - actual.pubkey().as_str(), + actual.pubkey().to_hex(), pubkey.to_ascii_lowercase(), "{} normalized author key", vector_id(vector) @@ -606,7 +606,7 @@ fn assert_author_reference( relay.is_none_or(|relay| radroots_event::ids::RadrootsRelayUrl::parse(relay).is_ok()); assert_eq!( actual.is_canonical(), - pubkey == actual.pubkey().as_str() && canonical_relay, + pubkey == actual.pubkey().to_hex() && canonical_relay, "{} author canonicality", vector_id(vector) ); diff --git a/crates/event_codec/tests/common/mod.rs b/crates/event_codec/tests/common/mod.rs @@ -5,7 +5,7 @@ use radroots_event::{ }; pub const EVENT_ID: &str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; -pub const AUTHOR: &str = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; +pub const AUTHOR: &str = "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df"; pub const EVENT_SIG: &str = concat!( "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" diff --git a/crates/event_codec/tests/coverage_edges.rs b/crates/event_codec/tests/coverage_edges.rs @@ -20,7 +20,7 @@ fn assert_invalid_kind<T>(result: Result<T, EventParseError>, expected: &'static fn parsed_args() -> (String, String, u64, u32, String, Vec<Vec<String>>, String) { ( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa".to_string(), - "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb".to_string(), + "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df".to_string(), 1, KIND_POST, String::new(), diff --git a/crates/event_codec/tests/fixtures/calendar_nip52_baseline.v1.json b/crates/event_codec/tests/fixtures/calendar_nip52_baseline.v1.json @@ -42,13 +42,13 @@ ["g", "C23NB62W20ST"], ["summary", " Weekly pickup "], ["image", "https://ordinary.example.test/images/market.jpg?size=large"], - ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - ["p", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "wss://relay.example.test/events"], - ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "", " host "], + ["p", "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df"], + ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "wss://relay.example.test/events"], + ["p", "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "", " host "], ["t", "vegetables"], ["t", "CSA"], ["r", "ipfs://bafybeigdyrzt/reference"], - ["a", "31924:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-calendar", "wss://relay.example.test"], + ["a", "31924:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-calendar", "wss://relay.example.test"], ["name", "Deprecated display name"], ["D", "extension", "preserved"] ] @@ -64,14 +64,14 @@ "summary": " Weekly pickup ", "image": "https://ordinary.example.test/images/market.jpg?size=large", "participants": [ - {"pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "relay": null, "role": null}, - {"pubkey": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "relay": "wss://relay.example.test/events", "role": null}, - {"pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "relay": null, "role": " host "} + {"pubkey": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "relay": null, "role": null}, + {"pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": "wss://relay.example.test/events", "role": null}, + {"pubkey": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "relay": null, "role": " host "} ], "categories": ["vegetables", "CSA"], "references": ["ipfs://bafybeigdyrzt/reference"], "calendar_requests": [ - {"calendar": "31924:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-calendar", "relay": "wss://relay.example.test"} + {"calendar": "31924:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-calendar", "relay": "wss://relay.example.test"} ], "legacy_name": "Deprecated display name", "date_day_extensions": [["D", "extension", "preserved"]] @@ -150,7 +150,7 @@ "input": { "kind": 31922, "content": "", - "tags": [["d", "bad-participant"], ["title", "Bad participant"], ["start", "2026-06-20"], ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", ""]] + "tags": [["d", "bad-participant"], ["title", "Bad participant"], ["start", "2026-06-20"], ["p", "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", ""]] }, "expected": { "error": "invalid_tag", "tag": "p" } }, @@ -160,7 +160,7 @@ "input": { "kind": 31922, "content": "", - "tags": [["d", "bad-request"], ["title", "Bad request"], ["start", "2026-06-20"], ["a", "31923:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:not-a-calendar"]] + "tags": [["d", "bad-request"], ["title", "Bad request"], ["start", "2026-06-20"], ["a", "31923:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:not-a-calendar"]] }, "expected": { "error": "invalid_tag", "tag": "a" } }, @@ -357,8 +357,8 @@ ["title", "Regional farm calendar"], ["description", "NIP-51 client-facing set description"], ["image", "https://ordinary.example.test/calendars/victoria.jpg"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:moss-street-market", "wss://date-relay.example.test/events"], - ["a", "31923:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:harvest-window", "WSS://Time-Relay.Example.Test/events"] + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:moss-street-market", "wss://date-relay.example.test/events"], + ["a", "31923:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:harvest-window", "WSS://Time-Relay.Example.Test/events"] ] }, "expected": { @@ -369,11 +369,11 @@ "image": "https://ordinary.example.test/calendars/victoria.jpg", "event_references": [ { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:moss-street-market", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:moss-street-market", "relay": "wss://date-relay.example.test/events" }, { - "coordinate": "31923:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:harvest-window", + "coordinate": "31923:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:harvest-window", "relay": "WSS://Time-Relay.Example.Test/events" } ] @@ -388,7 +388,7 @@ "tags": [ ["d", "uppercase-observed"], ["title", "Uppercase observed"], - ["a", "31922:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB:farm-tour", "WSS://Relay.Example.Test/events"] + ["a", "31922:585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF:farm-tour", "WSS://Relay.Example.Test/events"] ] }, "expected": { @@ -399,7 +399,7 @@ "image": null, "event_references": [ { - "coordinate": "31922:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB:farm-tour", + "coordinate": "31922:585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF:farm-tour", "relay": "WSS://Relay.Example.Test/events" } ] @@ -414,8 +414,8 @@ "tags": [ ["d", "duplicates-observed"], ["title", "Duplicates observed"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour", "wss://one.example.test"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour", "wss://two.example.test"] + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour", "wss://one.example.test"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour", "wss://two.example.test"] ] }, "expected": { @@ -426,11 +426,11 @@ "image": null, "event_references": [ { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour", "relay": "wss://one.example.test" }, { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour", "relay": "wss://two.example.test" } ] @@ -497,7 +497,7 @@ "tags": [ ["d", "bad-a-arity"], ["title", "Bad a arity"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour", "wss://relay.example.test", "unexpected"] + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour", "wss://relay.example.test", "unexpected"] ] }, "expected": {"error": "invalid_tag", "tag": "a"} @@ -518,7 +518,7 @@ "input": { "kind": 31924, "content": "", - "tags": [["d", "wrong-coordinate-kind"], ["title", "Wrong coordinate kind"], ["a", "31924:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:another-calendar"]] + "tags": [["d", "wrong-coordinate-kind"], ["title", "Wrong coordinate kind"], ["a", "31924:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:another-calendar"]] }, "expected": {"error": "invalid_tag", "tag": "a"} }, @@ -531,7 +531,7 @@ "tags": [ ["d", "bad-relay"], ["title", "Bad relay"], - ["a", "31923:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:harvest-window", "https://relay.example.test"] + ["a", "31923:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:harvest-window", "https://relay.example.test"] ] }, "expected": {"error": "invalid_tag", "tag": "a"} @@ -554,14 +554,14 @@ "content": "", "tags": [ ["d", "farm-tour-rsvp"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["status", "accepted"] ] }, "expected": { "d": "farm-tour-rsvp", "event_reference": { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour", "relay": null }, "revision_reference": null, @@ -580,28 +580,28 @@ "content": "I can help at the produce table.", "tags": [ ["d", "market-rsvp"], - ["a", "31923:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:market-shift", "wss://coordinate-relay.example.test/events"], - ["e", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "wss://event-relay.example.test/events"], + ["a", "31923:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:market-shift", "wss://coordinate-relay.example.test/events"], + ["e", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "wss://event-relay.example.test/events"], ["status", "tentative"], ["fb", "busy"], - ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "wss://author-relay.example.test/events"] + ["p", "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "wss://author-relay.example.test/events"] ] }, "expected": { "d": "market-rsvp", "event_reference": { - "coordinate": "31923:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:market-shift", + "coordinate": "31923:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:market-shift", "relay": "wss://coordinate-relay.example.test/events" }, "revision_reference": { - "id": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "id": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": "wss://event-relay.example.test/events" }, "status": "tentative", "observed_free_busy": "busy", "effective_free_busy": "busy", "author_hint": { - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "pubkey": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "relay": "wss://author-relay.example.test/events" }, "note": "I can help at the produce table." @@ -615,7 +615,7 @@ "content": "Unable to attend.", "tags": [ ["d", "declined-rsvp"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:seed-swap"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:seed-swap"], ["status", "declined"], ["fb", "busy"] ] @@ -623,7 +623,7 @@ "expected": { "d": "declined-rsvp", "event_reference": { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:seed-swap", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:seed-swap", "relay": null }, "revision_reference": null, @@ -642,28 +642,28 @@ "content": "", "tags": [ ["d", "uppercase-rsvp"], - ["a", "31922:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB:farm-tour", "WSS://Coordinate-Relay.Example.Test/events"], - ["e", "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC", "WSS://Event-Relay.Example.Test/events"], + ["a", "31922:585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF:farm-tour", "WSS://Coordinate-Relay.Example.Test/events"], + ["e", "E0266E3CFB0D2886F91C73F5F868F3B98273713E5FCD97C081663F5518A4B3AF", "WSS://Event-Relay.Example.Test/events"], ["status", "accepted"], ["fb", "free"], - ["p", "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", "WSS://Author-Relay.Example.Test/events"] + ["p", "585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF", "WSS://Author-Relay.Example.Test/events"] ] }, "expected": { "d": "uppercase-rsvp", "event_reference": { - "coordinate": "31922:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB:farm-tour", + "coordinate": "31922:585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF:farm-tour", "relay": "WSS://Coordinate-Relay.Example.Test/events" }, "revision_reference": { - "id": "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC", + "id": "E0266E3CFB0D2886F91C73F5F868F3B98273713E5FCD97C081663F5518A4B3AF", "relay": "WSS://Event-Relay.Example.Test/events" }, "status": "accepted", "observed_free_busy": "free", "effective_free_busy": "free", "author_hint": { - "pubkey": "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", + "pubkey": "585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF", "relay": "WSS://Author-Relay.Example.Test/events" }, "note": null @@ -675,7 +675,7 @@ "input": { "kind": 31925, "content": "", - "tags": [["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], ["status", "accepted"]] + "tags": [["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["status", "accepted"]] }, "expected": {"error": "missing_tag", "tag": "d"} }, @@ -691,7 +691,7 @@ "input": { "kind": 31925, "content": "", - "tags": [["d", "missing-status"], ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"]] + "tags": [["d", "missing-status"], ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"]] }, "expected": {"error": "missing_tag", "tag": "status"} }, @@ -701,7 +701,7 @@ "input": { "kind": 31925, "content": "", - "tags": [["d", "one"], ["d", "two"], ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], ["status", "accepted"]] + "tags": [["d", "one"], ["d", "two"], ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["status", "accepted"]] }, "expected": {"error": "duplicate_tag", "tag": "d"} }, @@ -713,8 +713,8 @@ "content": "", "tags": [ ["d", "duplicate-a"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], - ["a", "31923:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-shift"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], + ["a", "31923:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-shift"], ["status", "accepted"] ] }, @@ -726,7 +726,7 @@ "input": { "kind": 31925, "content": "", - "tags": [["d", "duplicate-status"], ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], ["status", "accepted"], ["status", "tentative"]] + "tags": [["d", "duplicate-status"], ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["status", "accepted"], ["status", "tentative"]] }, "expected": {"error": "duplicate_tag", "tag": "status"} }, @@ -738,8 +738,8 @@ "content": "", "tags": [ ["d", "duplicate-e"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], - ["e", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], + ["e", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], ["e", "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"], ["status", "accepted"] ] @@ -752,7 +752,7 @@ "input": { "kind": 31925, "content": "", - "tags": [["d", "duplicate-fb"], ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], ["status", "accepted"], ["fb", "free"], ["fb", "busy"]] + "tags": [["d", "duplicate-fb"], ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["status", "accepted"], ["fb", "free"], ["fb", "busy"]] }, "expected": {"error": "duplicate_tag", "tag": "fb"} }, @@ -764,10 +764,10 @@ "content": "", "tags": [ ["d", "duplicate-p"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["status", "accepted"], - ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - ["p", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"] + ["p", "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df"], + ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"] ] }, "expected": {"error": "duplicate_tag", "tag": "p"} @@ -780,7 +780,7 @@ "content": "", "tags": [ ["d", "bad-a-arity"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour", "wss://relay.example.test", "unexpected"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour", "wss://relay.example.test", "unexpected"], ["status", "accepted"] ] }, @@ -794,8 +794,8 @@ "content": "", "tags": [ ["d", "bad-e-arity"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], - ["e", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "wss://relay.example.test", "unexpected"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], + ["e", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "wss://relay.example.test", "unexpected"], ["status", "accepted"] ] }, @@ -809,9 +809,9 @@ "content": "", "tags": [ ["d", "bad-p-role"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["status", "accepted"], - ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "wss://relay.example.test", "host"] + ["p", "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "wss://relay.example.test", "host"] ] }, "expected": {"error": "invalid_tag", "tag": "p"} @@ -822,7 +822,7 @@ "input": { "kind": 31925, "content": "", - "tags": [["d", "wrong-kind"], ["a", "31924:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-calendar"], ["status", "accepted"]] + "tags": [["d", "wrong-kind"], ["a", "31924:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-calendar"], ["status", "accepted"]] }, "expected": {"error": "invalid_tag", "tag": "a"} }, @@ -838,7 +838,7 @@ "input": { "kind": 31925, "content": "", - "tags": [["d", "bad-event-id"], ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], ["e", "not-an-event-id"], ["status", "accepted"]] + "tags": [["d", "bad-event-id"], ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["e", "not-an-event-id"], ["status", "accepted"]] }, "expected": {"error": "invalid_tag", "tag": "e"} }, @@ -848,7 +848,7 @@ "input": { "kind": 31925, "content": "", - "tags": [["d", "bad-author"], ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], ["status", "accepted"], ["p", "not-a-pubkey"]] + "tags": [["d", "bad-author"], ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["status", "accepted"], ["p", "not-a-pubkey"]] }, "expected": {"error": "invalid_tag", "tag": "p"} }, @@ -858,7 +858,7 @@ "input": { "kind": 31925, "content": "", - "tags": [["d", "bad-a-relay"], ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour", "https://relay.example.test"], ["status", "accepted"]] + "tags": [["d", "bad-a-relay"], ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour", "https://relay.example.test"], ["status", "accepted"]] }, "expected": {"error": "invalid_tag", "tag": "a"} }, @@ -868,7 +868,7 @@ "input": { "kind": 31925, "content": "", - "tags": [["d", "bad-e-relay"], ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], ["e", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "https://relay.example.test"], ["status", "accepted"]] + "tags": [["d", "bad-e-relay"], ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["e", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "https://relay.example.test"], ["status", "accepted"]] }, "expected": {"error": "invalid_tag", "tag": "e"} }, @@ -878,7 +878,7 @@ "input": { "kind": 31925, "content": "", - "tags": [["d", "bad-p-relay"], ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], ["status", "accepted"], ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "https://relay.example.test"]] + "tags": [["d", "bad-p-relay"], ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["status", "accepted"], ["p", "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "https://relay.example.test"]] }, "expected": {"error": "invalid_tag", "tag": "p"} }, @@ -888,7 +888,7 @@ "input": { "kind": 31925, "content": "", - "tags": [["d", "bad-status"], ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], ["status", "maybe"]] + "tags": [["d", "bad-status"], ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["status", "maybe"]] }, "expected": {"error": "invalid_tag", "tag": "status"} }, @@ -898,7 +898,7 @@ "input": { "kind": 31925, "content": "", - "tags": [["d", "bad-fb"], ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], ["status", "accepted"], ["fb", "unknown"]] + "tags": [["d", "bad-fb"], ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["status", "accepted"], ["fb", "unknown"]] }, "expected": {"error": "invalid_tag", "tag": "fb"} }, @@ -960,7 +960,7 @@ "content": "", "tags": [ ["d", "bad-status-arity"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["status", "accepted", "unexpected"] ] }, @@ -974,7 +974,7 @@ "content": "", "tags": [ ["d", "bad-fb-arity"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-tour"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-tour"], ["status", "accepted"], ["fb", "free", "unexpected"] ] diff --git a/crates/event_codec/tests/fixtures/calendar_radroots_profile.v1.json b/crates/event_codec/tests/fixtures/calendar_radroots_profile.v1.json @@ -49,12 +49,12 @@ } }, "participants": [ - {"pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "relay": "wss://relay.example.test", "role": "host"} + {"pubkey": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "relay": "wss://relay.example.test", "role": "host"} ], "categories": ["csa", "vegetables"], "references": ["https://example.test/pickup-details"], "calendar_requests": [ - {"calendar": "31924:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-calendar", "relay": "wss://relay.example.test"} + {"calendar": "31924:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-calendar", "relay": "wss://relay.example.test"} ] }, "expected": { @@ -71,11 +71,11 @@ ["g", "c23nb62w20st"], ["summary", "Weekly pickup"], ["image", "https://media.example/aba72b48bb536e341ab81c5f86053981c443029766a4374ee86a4f56577ebc84.webp"], - ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "wss://relay.example.test", "host"], + ["p", "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "wss://relay.example.test", "host"], ["t", "csa"], ["t", "vegetables"], ["r", "https://example.test/pickup-details"], - ["a", "31924:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm-calendar", "wss://relay.example.test"] + ["a", "31924:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:farm-calendar", "wss://relay.example.test"] ] }, "media_verification": "byte_verified", @@ -188,7 +188,7 @@ "input": { "kind": 31922, "content": "", - "tags": [["d", "farm-tour"], ["title", "Urban farm tour"], ["start", "2026-07-18"], ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "WSS://relay.example.test"]] + "tags": [["d", "farm-tour"], ["title", "Urban farm tour"], ["start", "2026-07-18"], ["p", "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "WSS://relay.example.test"]] }, "expected": {"error": "non_canonical_field"} }, @@ -278,11 +278,11 @@ "list_description": "NIP-51 set description for compatible clients.", "event_references": [ { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": "wss://date-relay.example.test/events" }, { - "coordinate": "31923:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:CCCCCCCCCCCCCCCCCCCCCg", + "coordinate": "31923:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:CCCCCCCCCCCCCCCCCCCCCg", "relay": "wss://time-relay.example.test/events" } ] @@ -294,8 +294,8 @@ "tags": [ ["d", "AAAAAAAAAAAAAAAAAAAAAA"], ["title", "South Island farm schedule"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", "wss://date-relay.example.test/events"], - ["a", "31923:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:CCCCCCCCCCCCCCCCCCCCCg", "wss://time-relay.example.test/events"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "wss://date-relay.example.test/events"], + ["a", "31923:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:CCCCCCCCCCCCCCCCCCCCCg", "wss://time-relay.example.test/events"], ["description", "NIP-51 set description for compatible clients."] ] } @@ -320,7 +320,7 @@ }, "event_references": [ { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": null } ] @@ -332,7 +332,7 @@ "tags": [ ["d", "AAAAAAAAAAAAAAAAAAAAAA"], ["title", "Victoria farm calendar"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ"], ["image", "https://media.example/aba72b48bb536e341ab81c5f86053981c443029766a4374ee86a4f56577ebc84.webp"] ] }, @@ -360,11 +360,11 @@ "title": "Duplicate event calendar", "event_references": [ { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": "wss://one.example.test" }, { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": "wss://two.example.test" } ] @@ -379,7 +379,7 @@ "title": "Uppercase relay", "event_references": [ { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": "WSS://Relay.Example.Test/events" } ] @@ -394,7 +394,7 @@ "title": "Wrong coordinate kind", "event_references": [ { - "coordinate": "31924:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31924:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": null } ] @@ -410,8 +410,8 @@ "image": { "bytes_utf8": "victoria-calendar", "descriptor": { - "url": "https://media.example/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.webp", - "sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "url": "https://media.example/585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df.webp", + "sha256": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "size": 17, "type": "image/webp", "uploaded": 1784347200 @@ -444,8 +444,8 @@ "tags": [ ["d", "AAAAAAAAAAAAAAAAAAAAAA"], ["title", "South Island farm schedule"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", "wss://date-relay.example.test/events"], - ["a", "31923:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:CCCCCCCCCCCCCCCCCCCCCg", "wss://time-relay.example.test/events"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "wss://date-relay.example.test/events"], + ["a", "31923:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:CCCCCCCCCCCCCCCCCCCCCg", "wss://time-relay.example.test/events"], ["description", "NIP-51 set description for compatible clients."], ["image", "https://media.example/aba72b48bb536e341ab81c5f86053981c443029766a4374ee86a4f56577ebc84.webp"] ] @@ -456,11 +456,11 @@ "list_description": "NIP-51 set description for compatible clients.", "event_references": [ { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": "wss://date-relay.example.test/events" }, { - "coordinate": "31923:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:CCCCCCCCCCCCCCCCCCCCCg", + "coordinate": "31923:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:CCCCCCCCCCCCCCCCCCCCCg", "relay": "wss://time-relay.example.test/events" } ], @@ -477,7 +477,7 @@ "tags": [ ["d", "AAAAAAAAAAAAAAAAAAAAAA"], ["title", "Uppercase reference"], - ["a", "31922:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB:BBBBBBBBBBBBBBBBBBBBBQ", "WSS://Relay.Example.Test/events"] + ["a", "31922:585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF:BBBBBBBBBBBBBBBBBBBBBQ", "WSS://Relay.Example.Test/events"] ] }, "expected": {"error": "non_canonical_field", "field": "event_reference"} @@ -491,8 +491,8 @@ "tags": [ ["d", "AAAAAAAAAAAAAAAAAAAAAA"], ["title", "Duplicate reference"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", "wss://one.example.test"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", "wss://two.example.test"] + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "wss://one.example.test"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "wss://two.example.test"] ] }, "expected": {"error": "duplicate_event_reference"} @@ -527,7 +527,7 @@ "input": { "d": "DDDDDDDDDDDDDDDDDDDDDw", "event_reference": { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": null }, "status": "accepted" @@ -538,7 +538,7 @@ "content": "", "tags": [ ["d", "DDDDDDDDDDDDDDDDDDDDDw"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ"], ["status", "accepted"] ] } @@ -550,17 +550,17 @@ "input": { "d": "DDDDDDDDDDDDDDDDDDDDDw", "event_reference": { - "coordinate": "31923:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31923:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": "wss://coordinate-relay.example.test/events" }, "revision_reference": { - "id": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "id": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": "wss://event-relay.example.test/events" }, "status": "tentative", "free_busy": "busy", "author_hint": { - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "pubkey": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "relay": "wss://author-relay.example.test/events" }, "note": "I can help with the wash-pack shift." @@ -571,11 +571,11 @@ "content": "I can help with the wash-pack shift.", "tags": [ ["d", "DDDDDDDDDDDDDDDDDDDDDw"], - ["a", "31923:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", "wss://coordinate-relay.example.test/events"], + ["a", "31923:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "wss://coordinate-relay.example.test/events"], ["status", "tentative"], - ["e", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "wss://event-relay.example.test/events"], + ["e", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "wss://event-relay.example.test/events"], ["fb", "busy"], - ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "wss://author-relay.example.test/events"] + ["p", "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "wss://author-relay.example.test/events"] ] }, "observed_free_busy": "busy", @@ -588,7 +588,7 @@ "input": { "d": "DDDDDDDDDDDDDDDDDDDDDw", "event_reference": { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": null }, "status": "declined", @@ -602,7 +602,7 @@ "input": { "d": "farm-tour-rsvp", "event_reference": { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": null }, "status": "accepted" @@ -615,11 +615,11 @@ "input": { "d": "DDDDDDDDDDDDDDDDDDDDDw", "event_reference": { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": null }, "revision_reference": { - "id": "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC", + "id": "E0266E3CFB0D2886F91C73F5F868F3B98273713E5FCD97C081663F5518A4B3AF", "relay": null }, "status": "accepted" @@ -632,12 +632,12 @@ "input": { "d": "DDDDDDDDDDDDDDDDDDDDDw", "event_reference": { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": null }, "status": "accepted", "author_hint": { - "pubkey": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null } }, @@ -649,7 +649,7 @@ "input": { "d": "DDDDDDDDDDDDDDDDDDDDDw", "event_reference": { - "coordinate": "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": "WSS://Relay.Example.Test/events" }, "status": "accepted" @@ -662,7 +662,7 @@ "input": { "d": "DDDDDDDDDDDDDDDDDDDDDw", "event_reference": { - "coordinate": "31924:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31924:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": null }, "status": "accepted" @@ -677,7 +677,7 @@ "content": "", "tags": [ ["d", "DDDDDDDDDDDDDDDDDDDDDw"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ"], ["status", "accepted"] ] }, @@ -696,25 +696,25 @@ "content": "I can help with the wash-pack shift.", "tags": [ ["d", "DDDDDDDDDDDDDDDDDDDDDw"], - ["a", "31923:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", "wss://coordinate-relay.example.test/events"], - ["e", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "wss://event-relay.example.test/events"], + ["a", "31923:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "wss://coordinate-relay.example.test/events"], + ["e", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "wss://event-relay.example.test/events"], ["status", "tentative"], ["fb", "busy"], - ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "wss://author-relay.example.test/events"] + ["p", "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "wss://author-relay.example.test/events"] ] }, "expected": { "d": "DDDDDDDDDDDDDDDDDDDDDw", "event_reference": { - "coordinate": "31923:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", + "coordinate": "31923:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "relay": "wss://coordinate-relay.example.test/events" }, "revision_reference": { - "id": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "id": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": "wss://event-relay.example.test/events" }, "author_hint": { - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "pubkey": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "relay": "wss://author-relay.example.test/events" }, "status": "tentative", @@ -730,7 +730,7 @@ "content": "Unable to attend.", "tags": [ ["d", "DDDDDDDDDDDDDDDDDDDDDw"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ"], ["status", "declined"], ["fb", "busy"] ] @@ -750,10 +750,10 @@ "content": "", "tags": [ ["d", "DDDDDDDDDDDDDDDDDDDDDw"], - ["a", "31922:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB:BBBBBBBBBBBBBBBBBBBBBQ", "WSS://Coordinate-Relay.Example.Test/events"], - ["e", "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC", "WSS://Event-Relay.Example.Test/events"], + ["a", "31922:585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF:BBBBBBBBBBBBBBBBBBBBBQ", "WSS://Coordinate-Relay.Example.Test/events"], + ["e", "E0266E3CFB0D2886F91C73F5F868F3B98273713E5FCD97C081663F5518A4B3AF", "WSS://Event-Relay.Example.Test/events"], ["status", "accepted"], - ["p", "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", "WSS://Author-Relay.Example.Test/events"] + ["p", "585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF", "WSS://Author-Relay.Example.Test/events"] ] }, "expected": {"error": "non_canonical_field"} @@ -766,9 +766,9 @@ "content": "", "tags": [ ["d", "DDDDDDDDDDDDDDDDDDDDDw"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ"], ["status", "accepted"], - ["p", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"] + ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"] ] }, "expected": {"error": "author_hint_mismatch"} @@ -781,7 +781,7 @@ "content": "", "tags": [ ["d", "farm-tour-rsvp"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ"], ["status", "accepted"] ] }, @@ -796,7 +796,7 @@ "tags": [ ["d", "AAAAAAAAAAAAAAAAAAAAAA"], ["title", "Uppercase coordinate"], - ["a", "31922:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB:BBBBBBBBBBBBBBBBBBBBBQ"] + ["a", "31922:585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF:BBBBBBBBBBBBBBBBBBBBBQ"] ] }, "expected": {"error": "non_canonical_field", "field": "event_reference"} @@ -810,7 +810,7 @@ "tags": [ ["d", "AAAAAAAAAAAAAAAAAAAAAA"], ["title", "Uppercase relay"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", "WSS://Relay.Example.Test/events"] + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "WSS://Relay.Example.Test/events"] ] }, "expected": {"error": "non_canonical_field", "field": "event_reference"} @@ -823,7 +823,7 @@ "content": "", "tags": [ ["d", "DDDDDDDDDDDDDDDDDDDDDw"], - ["a", "31922:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB:BBBBBBBBBBBBBBBBBBBBBQ"], + ["a", "31922:585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF:BBBBBBBBBBBBBBBBBBBBBQ"], ["status", "accepted"] ] }, @@ -837,8 +837,8 @@ "content": "", "tags": [ ["d", "DDDDDDDDDDDDDDDDDDDDDw"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ"], - ["e", "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ"], + ["e", "E0266E3CFB0D2886F91C73F5F868F3B98273713E5FCD97C081663F5518A4B3AF"], ["status", "accepted"] ] }, @@ -852,9 +852,9 @@ "content": "", "tags": [ ["d", "DDDDDDDDDDDDDDDDDDDDDw"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ"], ["status", "accepted"], - ["p", "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"] + ["p", "585591529DA0BAB31B3B1B1F986611CF5F435DCA84F978C89EE8A40CCA7103DF"] ] }, "expected": {"error": "non_canonical_field", "field": "author_hint"} @@ -867,7 +867,7 @@ "content": "", "tags": [ ["d", "DDDDDDDDDDDDDDDDDDDDDw"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ", "WSS://Coordinate-Relay.Example.Test/events"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ", "WSS://Coordinate-Relay.Example.Test/events"], ["status", "accepted"] ] }, @@ -881,8 +881,8 @@ "content": "", "tags": [ ["d", "DDDDDDDDDDDDDDDDDDDDDw"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ"], - ["e", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "WSS://Event-Relay.Example.Test/events"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ"], + ["e", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "WSS://Event-Relay.Example.Test/events"], ["status", "accepted"] ] }, @@ -896,9 +896,9 @@ "content": "", "tags": [ ["d", "DDDDDDDDDDDDDDDDDDDDDw"], - ["a", "31922:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:BBBBBBBBBBBBBBBBBBBBBQ"], + ["a", "31922:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:BBBBBBBBBBBBBBBBBBBBBQ"], ["status", "accepted"], - ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "WSS://Author-Relay.Example.Test/events"] + ["p", "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "WSS://Author-Relay.Example.Test/events"] ] }, "expected": {"error": "non_canonical_field", "field": "author_hint"} diff --git a/crates/event_codec/tests/fixtures/comment_verified_profile.v1.json b/crates/event_codec/tests/fixtures/comment_verified_profile.v1.json @@ -14560,7 +14560,7 @@ "id": "project_parent_author_mismatch", "kind": "social.comment.project_verified_event.invalid", "input": { - "event_json": "{\"id\":\"c44cc89ecf98c8cf2e596ea8bb7b99993fcd2767c0ed2842c8ca3d8281342c0a\",\"pubkey\":\"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df\",\"created_at\":1800000200,\"kind\":1111,\"tags\":[[\"E\",\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"wss://victoria.example\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"K\",\"30402\"],[\"P\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\",\"wss://victoria.example\"],[\"e\",\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"wss://victoria.example\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"k\",\"30402\"],[\"p\",\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\",\"wss://victoria.example\"]],\"content\":\"Are these carrots available Saturday?\",\"sig\":\"ca7d4eff81d73e21fbd9459733b8e4cb8ea92661b2c2b4fcc23dbf68bdd648e07243c6c78260592957b02b64044ee7e9af93a98b754b3177425e637af7592497\"}" + "event_json": "{\"id\":\"85d1e0149f8263efc02185a1bba50c3955fdee1fd7598e197b20b493f8e5a022\",\"pubkey\":\"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df\",\"created_at\":1800000200,\"kind\":1111,\"tags\":[[\"E\",\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"wss://victoria.example\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"K\",\"30402\"],[\"P\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\",\"wss://victoria.example\"],[\"e\",\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"wss://victoria.example\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"k\",\"30402\"],[\"p\",\"1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c\",\"wss://victoria.example\"]],\"content\":\"Are these carrots available Saturday?\",\"sig\":\"cb00151021c7152d8990d1d84c1781c9f9e835909c94485231363e2223220d6a480debb1abc75d6f450c4c63050966a4688740621f33cbe05cd0b181c50003ef\"}" }, "expected": { "error": "comment_parent_author_mismatch" diff --git a/crates/event_codec/tests/fixtures/deletion_verified_profile.v1.json b/crates/event_codec/tests/fixtures/deletion_verified_profile.v1.json @@ -213,8 +213,8 @@ "kind": "social.deletion_request.build_authored_draft.valid", "input": { "address_targets": [ - "31923:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd:market", - "30000:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:produce" + "31923:5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4:market", + "30000:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:produce" ], "content": "superseded", "event_targets": [ @@ -250,11 +250,11 @@ ], [ "a", - "30000:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:produce" + "30000:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:produce" ], [ "a", - "31923:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd:market" + "31923:5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4:market" ], [ "k", @@ -13117,51 +13117,51 @@ "id": "nip09_project_signed_address_replaceable_boundaries", "kind": "social.deletion_request.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"ca629e60259cd0ac499e85fe3e3c97c9a846311ad17cf9576bf00fe7dd349e5c\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":2,\"kind\":5,\"tags\":[[\"a\",\"0:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\"],[\"a\",\"3:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:\"],[\"a\",\"10000:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:\"],[\"a\",\"19999:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd:\"]],\"content\":\"\",\"sig\":\"8b29a65a47a30047eaab29ad774f6afb116be114937ea7a7aeb158cd7fc81f08dfa413386942fc4a7db0e64875c94ca4aa2f2272696c62b424649d261afafd44\"}" + "event_json": "{\"id\":\"e0ef10c9e31c32deabe3cb516f289415de0266f8cb96cd2c603f8db1ed4b0d9a\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":2,\"kind\":5,\"tags\":[[\"a\",\"0:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:\"],[\"a\",\"3:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:\"],[\"a\",\"10000:1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c:\"],[\"a\",\"19999:5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4:\"]],\"content\":\"\",\"sig\":\"1c1ab28a42f8b49daf29cfd4511d46a54a6ee32ffdab2d9bfede5fb55045140023eb4ddc57284e0cc9984f3c94167bd4f996ab74c486338d216c75c83f541c72\"}" }, "expected": { "address_targets": [ { - "coordinate": "0:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:", + "coordinate": "0:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:", "identifier": "", "kind": 0, - "pubkey": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "pubkey": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "raw_tag": [ "a", - "0:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:" + "0:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:" ], "tag_index": 0 }, { - "coordinate": "10000:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:", + "coordinate": "10000:1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c:", "identifier": "", "kind": 10000, - "pubkey": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "pubkey": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c", "raw_tag": [ "a", - "10000:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:" + "10000:1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c:" ], "tag_index": 2 }, { - "coordinate": "19999:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd:", + "coordinate": "19999:5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4:", "identifier": "", "kind": 19999, - "pubkey": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "pubkey": "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4", "raw_tag": [ "a", - "19999:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd:" + "19999:5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4:" ], "tag_index": 3 }, { - "coordinate": "3:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:", + "coordinate": "3:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:", "identifier": "", "kind": 3, - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "raw_tag": [ "a", - "3:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:" + "3:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:" ], "tag_index": 1 } @@ -13173,19 +13173,19 @@ "raw_tags": [ [ "a", - "0:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:" + "0:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:" ], [ "a", - "3:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:" + "3:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:" ], [ "a", - "10000:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:" + "10000:1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c:" ], [ "a", - "19999:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd:" + "19999:5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4:" ] ] } @@ -13194,29 +13194,29 @@ "id": "nip09_project_signed_addressable_boundaries", "kind": "social.deletion_request.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"550e49ccc8f4f479bef48605d375ba4ff5f0f8a0fcac449234ace7419b42fa99\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":3,\"kind\":5,\"tags\":[[\"a\",\"30000:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\"],[\"a\",\"39999:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm:row:7\"]],\"content\":\"\",\"sig\":\"897bb197ab6a688ecc057e57151fc24519a1fddb6f6f734821effc8d0a9d2629c13cf13797582b5572c5bc6f3a0a6d4cb96a58ffdfbf5d910deae99e32399a2d\"}" + "event_json": "{\"id\":\"1d3c5d5f0e141adbd65a871ab9ac5c742f75c70ec729631945a73c461dd01fa4\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":3,\"kind\":5,\"tags\":[[\"a\",\"30000:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:\"],[\"a\",\"39999:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:farm:row:7\"]],\"content\":\"\",\"sig\":\"ac7e31bdeab52734e8ef6913c0e23867e791c793d0e79501620a1144ba3e41216fb650c5ca23e5f0b2d4cdb40b15da525cde9bdffe09bcf7e97744178abcb651\"}" }, "expected": { "address_targets": [ { - "coordinate": "30000:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:", + "coordinate": "30000:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:", "identifier": "", "kind": 30000, - "pubkey": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "pubkey": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "raw_tag": [ "a", - "30000:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:" + "30000:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:" ], "tag_index": 0 }, { - "coordinate": "39999:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm:row:7", + "coordinate": "39999:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:farm:row:7", "identifier": "farm:row:7", "kind": 39999, - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "raw_tag": [ "a", - "39999:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm:row:7" + "39999:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:farm:row:7" ], "tag_index": 1 } @@ -13228,11 +13228,11 @@ "raw_tags": [ [ "a", - "30000:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:" + "30000:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:" ], [ "a", - "39999:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:farm:row:7" + "39999:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:farm:row:7" ] ] } @@ -13241,18 +13241,18 @@ "id": "nip09_project_signed_mixed_raw_retention", "kind": "social.deletion_request.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"4206395f0c18d86536bd57e6ca38cbb48dcf44ac1d0a22904190442445d2fc3f\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":4,\"kind\":5,\"tags\":[[\"x\",\"unknown\",\"retained\"],[\"e\",\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\",\"wss://relay.example\",\"root\"],[\"a\",\"30000:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:produce\",\"trailing\"],[\"k\",\"30000\",\"trailing\"]],\"content\":\"raw order\",\"sig\":\"d6078beab27d6ed5c3427a98639a081c255d2faed7efd89207f1839b40f5b06c1584f91224a9a3e13360861923488f89147091c130c701cb3053ec27e1a0d7dc\"}" + "event_json": "{\"id\":\"f50b6892d049f34e941eb691ef4a4b956217a44ca68f3aa0c4ef7e0ca360d092\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":4,\"kind\":5,\"tags\":[[\"x\",\"unknown\",\"retained\"],[\"e\",\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\",\"wss://relay.example\",\"root\"],[\"a\",\"30000:1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c:produce\",\"trailing\"],[\"k\",\"30000\",\"trailing\"]],\"content\":\"raw order\",\"sig\":\"df09f81f6b6ca7e4c18aee1a9476ed56b6fbe5acba2ce7be73f6a617db7db9a522691f64034377902cfd0f36750992fd2984c1c334f49a2f49ba3d2a7c0a66a7\"}" }, "expected": { "address_targets": [ { - "coordinate": "30000:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:produce", + "coordinate": "30000:1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c:produce", "identifier": "produce", "kind": 30000, - "pubkey": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "pubkey": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c", "raw_tag": [ "a", - "30000:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:produce", + "30000:1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c:produce", "trailing" ], "tag_index": 2 @@ -13297,7 +13297,7 @@ ], [ "a", - "30000:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:produce", + "30000:1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c:produce", "trailing" ], [ @@ -13312,18 +13312,18 @@ "id": "nip09_project_signed_duplicate_targets_first_provenance", "kind": "social.deletion_request.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"ef7b4f50235a637d9859d7f5ad879bc1e423a59da6835e82cbcd7c368c733b26\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":5,\"kind\":5,\"tags\":[[\"e\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\",\"first\"],[\"e\",\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"second\"],[\"a\",\"030000:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB:produce\",\"first\"],[\"a\",\"30000:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:produce\",\"second\"]],\"content\":\"\",\"sig\":\"dded0dcec9cebf45c443ec736ccf096911cf57adfd45b2b3143c60e26c95582167c05bbce452b0adcbf333fe4471c0c95d58fc466a87e6349820301d738047b3\"}" + "event_json": "{\"id\":\"b922ee8c829b7caf95227a5b290511f81a7f7c56b98af57673adfd5bbf8b4834\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":5,\"kind\":5,\"tags\":[[\"e\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\",\"first\"],[\"e\",\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"second\"],[\"a\",\"030000:E0266E3CFB0D2886F91C73F5F868F3B98273713E5FCD97C081663F5518A4B3AF:produce\",\"first\"],[\"a\",\"30000:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:produce\",\"second\"]],\"content\":\"\",\"sig\":\"c945d8be7013cc8db307a70d271977fedfbc479416f457baf08b18a4e9e64923420af6156bf44e84e6c466e71ecd4c1baf529384067fd8d2f82d4fc0802a1534\"}" }, "expected": { "address_targets": [ { - "coordinate": "30000:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:produce", + "coordinate": "30000:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:produce", "identifier": "produce", "kind": 30000, - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "raw_tag": [ "a", - "030000:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB:produce", + "030000:E0266E3CFB0D2886F91C73F5F868F3B98273713E5FCD97C081663F5518A4B3AF:produce", "first" ], "tag_index": 2 @@ -13356,12 +13356,12 @@ ], [ "a", - "030000:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB:produce", + "030000:E0266E3CFB0D2886F91C73F5F868F3B98273713E5FCD97C081663F5518A4B3AF:produce", "first" ], [ "a", - "30000:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:produce", + "30000:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:produce", "second" ] ] @@ -13371,29 +13371,29 @@ "id": "nip09_project_signed_canonical_effect_sorting", "kind": "social.deletion_request.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"682de0df23f548c7e1e8272ff7776c5574ea12b18041e46004f6045263433a27\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":6,\"kind\":5,\"tags\":[[\"e\",\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\"],[\"a\",\"31923:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd:market\"],[\"e\",\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"],[\"a\",\"30000:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:produce\"]],\"content\":\"\",\"sig\":\"9d6a1bc42f42739042c0bef26ff5557176f571b152cd30b730b3a2ea388a874827f7ecf1ed4241234fe50143da77640542ecd5af4263900981760d1be616eea2\"}" + "event_json": "{\"id\":\"c85bb88aff6fe36198851dbc8638ad8b288a861d18d4834ed61e3545cde97a09\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":6,\"kind\":5,\"tags\":[[\"e\",\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\"],[\"a\",\"31923:5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4:market\"],[\"e\",\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"],[\"a\",\"30000:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:produce\"]],\"content\":\"\",\"sig\":\"1f15aeb3016d5533c675d227b79d59f59e77c78cbbe4d59ec25a2d7624c8836c162990e1b388c6c0ee6800e18f512b0216a2ade79788d1b032c0f74278558f3a\"}" }, "expected": { "address_targets": [ { - "coordinate": "30000:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:produce", + "coordinate": "30000:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:produce", "identifier": "produce", "kind": 30000, - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "raw_tag": [ "a", - "30000:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:produce" + "30000:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:produce" ], "tag_index": 3 }, { - "coordinate": "31923:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd:market", + "coordinate": "31923:5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4:market", "identifier": "market", "kind": 31923, - "pubkey": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "pubkey": "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4", "raw_tag": [ "a", - "31923:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd:market" + "31923:5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4:market" ], "tag_index": 1 } @@ -13426,7 +13426,7 @@ ], [ "a", - "31923:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd:market" + "31923:5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4:market" ], [ "e", @@ -13434,7 +13434,7 @@ ], [ "a", - "30000:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:produce" + "30000:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:produce" ] ] } @@ -13443,18 +13443,18 @@ "id": "nip09_project_signed_kind_advisory_diagnostics", "kind": "social.deletion_request.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"e8c11c5d1fd81bee0423a6f20db42786cc36f4c8922845c22ad0753bc4d10447\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":7,\"kind\":5,\"tags\":[[\"a\",\"30000:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:produce\"],[\"k\",\"30000\"],[\"k\"],[\"k\",\"030000\"],[\"k\",\"30000\",\"duplicate\"],[\"k\",\"5\"]],\"content\":\"\",\"sig\":\"3c7b7ad36ef173e61d85cd22989e5694e8373c670bf3b84dabf602c4dc17313eba107952969ac92521900e7f10a1fce80a6f90120e09705740a3dc5b4491c1a9\"}" + "event_json": "{\"id\":\"a7759259b243f84005168ed7a11c626d1156c99393e51610c54f511ece3ea516\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":7,\"kind\":5,\"tags\":[[\"a\",\"30000:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:produce\"],[\"k\",\"30000\"],[\"k\"],[\"k\",\"030000\"],[\"k\",\"30000\",\"duplicate\"],[\"k\",\"5\"]],\"content\":\"\",\"sig\":\"6205f197be2f061e31950234b4ad3a9b90659710a2d65836f8d243517fc4e1aac2f3d54f4eab401dba81d6481be687a2a0df9c482e6cc575ace1e5b3f405a065\"}" }, "expected": { "address_targets": [ { - "coordinate": "30000:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:produce", + "coordinate": "30000:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:produce", "identifier": "produce", "kind": 30000, - "pubkey": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "pubkey": "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df", "raw_tag": [ "a", - "30000:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:produce" + "30000:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:produce" ], "tag_index": 0 } @@ -13516,7 +13516,7 @@ "raw_tags": [ [ "a", - "30000:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:produce" + "30000:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:produce" ], [ "k", @@ -23395,7 +23395,7 @@ "id": "nip09_project_signed_address_target_unsupported_kind", "kind": "social.deletion_request.project_verified_event.invalid", "input": { - "event_json": "{\"id\":\"9489e523cdf3103b1608cd03a4c31f8c2f83fa8b092521cac782ee8ff7e006ad\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":33,\"kind\":5,\"tags\":[[\"a\",\"20000:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\"]],\"content\":\"\",\"sig\":\"b3479000500fd8453232d995e1c36073ce20f0ef579ddcc6122c9dd23525b37d726fe1f0a98e036a208726876a737dfb6fdc21acb10e28cf59ed80962b2a0ad2\"}" + "event_json": "{\"id\":\"5c6e3d68c69fa58615cb7db74edaabf055390101947bcced291ba00edd8b2a7d\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":33,\"kind\":5,\"tags\":[[\"a\",\"20000:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:\"]],\"content\":\"\",\"sig\":\"df67f12a606578fd9da58fe2e2edf1964844d816afc08d34b625d976dc536a6d218953c38f8151265ca6f4f4cdac6a973fba40c4925e27756a54d072379adea8\"}" }, "expected": { "error": "deletion_address_target_invalid" @@ -23405,7 +23405,7 @@ "id": "nip09_project_signed_address_target_identifier_forbidden", "kind": "social.deletion_request.project_verified_event.invalid", "input": { - "event_json": "{\"id\":\"cb5e015b280e5a5cdce1aab86ca69ff0b5ab02463e59e385aa2423b91850c374\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":34,\"kind\":5,\"tags\":[[\"a\",\"10000:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:forbidden\"]],\"content\":\"\",\"sig\":\"689d9788b632d8400d9f29a460b94402ff0dac7ef5a1df971235ce32fe91f758ecee66dfee6c208b6eef6d3dff6d42c874e7b6ea10d1a8a7ecc5cc4fdf167985\"}" + "event_json": "{\"id\":\"d3dabd8d980b0303eaf0384984ae3e30fcd4a3d4780d4bc03645427fab3ec48a\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":34,\"kind\":5,\"tags\":[[\"a\",\"10000:585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df:forbidden\"]],\"content\":\"\",\"sig\":\"afd5a1c45d68e29c1747d608d4ced1afbe9c3079a4df2696184a9a354a2b360a8881eb35764a17d2cbe66fe69a107237058936bf5259d7e4fa0197d48cc9eef7\"}" }, "expected": { "error": "deletion_address_target_invalid" @@ -23554,18 +23554,18 @@ "id": "nip09_admit_signed_address_target", "kind": "social.deletion_request.verify_and_admit_event.valid", "input": { - "event_json": "{\"id\":\"ca06409e5b9f6020a4ddd64c01cddb21a60bc0c878aae16e4e86ec862db0259a\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":51,\"kind\":5,\"tags\":[[\"a\",\"30000:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:produce\"]],\"content\":\"\",\"sig\":\"3a9d2b64027f54aa7c4cf7a71f59f46626c7f7da328c14f15df0e1e20c135d6c39249ecd87ae2a52cd09fa6248b2124c1dde1b7c0c7a79cec859d1314a4ae050\"}" + "event_json": "{\"id\":\"1db5e2667b7de3f36f5bdff85ca82d5edfb76936bcdf3a15042b94866f835117\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":51,\"kind\":5,\"tags\":[[\"a\",\"30000:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:produce\"]],\"content\":\"\",\"sig\":\"5cec31910d443b971d276589b8770dfe6692f9e5dc7169a9359d4222c1ecb9cbc3366bc649388d5bef6ac92f84ed5e46025013143fd1b5457d465e5b94d2d24e\"}" }, "expected": { "address_targets": [ { - "coordinate": "30000:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:produce", + "coordinate": "30000:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:produce", "identifier": "produce", "kind": 30000, - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "raw_tag": [ "a", - "30000:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:produce" + "30000:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:produce" ], "tag_index": 0 } @@ -23577,7 +23577,7 @@ "raw_tags": [ [ "a", - "30000:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:produce" + "30000:e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af:produce" ] ] } @@ -23586,18 +23586,18 @@ "id": "nip09_admit_signed_mixed_tolerant_projection", "kind": "social.deletion_request.verify_and_admit_event.valid", "input": { - "event_json": "{\"id\":\"be56e90b66e7e2c8bbd72d97e940f28a9da0549e3ff3ea9fb76246f08f8054e2\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":52,\"kind\":5,\"tags\":[[\"x\",\"retained\"],[\"e\",\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\",\"relay\"],[\"a\",\"31923:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:market\",\"extra\"],[\"k\",\"31923\"]],\"content\":\"withdrawn\",\"sig\":\"24b858e8f25c939112a4f69a9d5e5c53e7deeffcefe3311adacb2ad6ff1ad4df7c247f5e92d90efb1d023dcc3d733f3e71f63c3d66e10464db1b8e2156663c92\"}" + "event_json": "{\"id\":\"114bc1c32e196912dbe03352046f1718e0e66363711ec4c3491891b04080108a\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":52,\"kind\":5,\"tags\":[[\"x\",\"retained\"],[\"e\",\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\",\"relay\"],[\"a\",\"31923:1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c:market\",\"extra\"],[\"k\",\"31923\"]],\"content\":\"withdrawn\",\"sig\":\"8e0ee72c28606705747eae21f0cbb546ea22946b160c46353b673e07004093aea29650be9cd4d12d34111a8f0efac9b7140f7d3f3f9a46c5ec9b7a00887b89c8\"}" }, "expected": { "address_targets": [ { - "coordinate": "31923:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:market", + "coordinate": "31923:1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c:market", "identifier": "market", "kind": 31923, - "pubkey": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "pubkey": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c", "raw_tag": [ "a", - "31923:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:market", + "31923:1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c:market", "extra" ], "tag_index": 2 @@ -23638,7 +23638,7 @@ ], [ "a", - "31923:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:market", + "31923:1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c:market", "extra" ], [ diff --git a/crates/event_codec/tests/fixtures/post_verified_profiles.v1.json b/crates/event_codec/tests/fixtures/post_verified_profiles.v1.json @@ -143,7 +143,7 @@ "content": "Direct reply", "root": { "event_id": "1111111111111111111111111111111111111111111111111111111111111111", - "author": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "author": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": "wss://root.relay.example" } }, @@ -152,7 +152,7 @@ "content": "Direct reply", "tags": [ ["e", "1111111111111111111111111111111111111111111111111111111111111111", "wss://root.relay.example", "root"], - ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"] + ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"] ] } }, @@ -163,12 +163,12 @@ "content": "Nested reply", "root": { "event_id": "1111111111111111111111111111111111111111111111111111111111111111", - "author": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "author": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null }, "parent": { "event_id": "2222222222222222222222222222222222222222222222222222222222222222", - "author": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "author": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c", "relay": "wss://parent.relay.example" } }, @@ -178,8 +178,8 @@ "tags": [ ["e", "1111111111111111111111111111111111111111111111111111111111111111", "", "root"], ["e", "2222222222222222222222222222222222222222222222222222222222222222", "wss://parent.relay.example", "reply"], - ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - ["p", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"] + ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], + ["p", "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c"] ] } }, @@ -190,12 +190,12 @@ "content": "Ambiguous", "root": { "event_id": "1111111111111111111111111111111111111111111111111111111111111111", - "author": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "author": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null }, "parent": { "event_id": "1111111111111111111111111111111111111111111111111111111111111111", - "author": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "author": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c", "relay": null } }, @@ -210,7 +210,7 @@ "content": "Invalid", "root": { "event_id": "not-an-event-id", - "author": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "author": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null } }, @@ -225,7 +225,7 @@ "content": "Canonical relay", "root": { "event_id": "1111111111111111111111111111111111111111111111111111111111111111", - "author": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "author": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": "wss://[2001:db8::1]:8443/nostr?region=ca-bc&next=%2Ffeed" } }, @@ -234,7 +234,7 @@ "content": "Canonical relay", "tags": [ ["e", "1111111111111111111111111111111111111111111111111111111111111111", "wss://[2001:db8::1]:8443/nostr?region=ca-bc&next=%2Ffeed", "root"], - ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"] + ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"] ] } }, @@ -245,7 +245,7 @@ "content": "Invalid relay", "root": { "event_id": "1111111111111111111111111111111111111111111111111111111111111111", - "author": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "author": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": "wss://%" } }, @@ -260,7 +260,7 @@ "content": "Invalid relay", "root": { "event_id": "1111111111111111111111111111111111111111111111111111111111111111", - "author": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "author": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": "wss://%zz" } }, @@ -275,7 +275,7 @@ "content": "Invalid relay", "root": { "event_id": "1111111111111111111111111111111111111111111111111111111111111111", - "author": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "author": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": "wss://256.1.1.1" } }, @@ -290,7 +290,7 @@ "content": "Invalid relay", "root": { "event_id": "1111111111111111111111111111111111111111111111111111111111111111", - "author": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "author": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": "wss://[v1.foo]" } }, @@ -305,7 +305,7 @@ "content": "Invalid relay", "root": { "event_id": "1111111111111111111111111111111111111111111111111111111111111111", - "author": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "author": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": "wss://relay.example:" } }, @@ -320,7 +320,7 @@ "content": "Invalid relay", "root": { "event_id": "1111111111111111111111111111111111111111111111111111111111111111", - "author": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "author": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": "wss://relay.example:0" } }, @@ -335,7 +335,7 @@ "content": "Invalid relay", "root": { "event_id": "1111111111111111111111111111111111111111111111111111111111111111", - "author": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "author": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": "wss://relay.example:65536" } }, @@ -347,7 +347,7 @@ "id": "project_signed_nip10_marked_direct", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"2340fc3fec291f4d4429bf13bf23cc3b7ec8589aa5e6426a5fc5a25bfcf1a896\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000001,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"Direct reply\",\"sig\":\"16afb66cf2e30450a1055d697044b0f27835352553f32f7ac8d18387cc27861dfde3bb820a8882c00f933c13d4c967df5d5db986cc228a80dd3d291841bf08cd\"}" + "event_json": "{\"id\":\"d62b9340ac9808fc84a751788d017344ede91aea1c89081be3f7bff4a2266354\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000001,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"Direct reply\",\"sig\":\"206758bee31328a53457e3190b046a4a184941223f4e8ed1696db28d71c9af03138fe9add32d5e97d6f3b50bd0f78e4d5a91629dbf4d12aedd4315ce96c97e8c\"}" }, "expected": { "style": "marked", @@ -365,8 +365,8 @@ "participants": [ { "tag_index": 1, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null } ], @@ -377,7 +377,7 @@ "id": "project_signed_nip10_marked_with_citation", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"b6bd8c4e2c8e3098a0b6fdbefbf7a25285887519e2ea58738af4221ddb5fd39e\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000016,\"kind\":1,\"tags\":[[\"e\",\"3333333333333333333333333333333333333333333333333333333333333333\",\"wss://relay.example\",\"\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"],[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"Marked reply with citation\",\"sig\":\"9f6516def04521e4e9c9b27f1225e43c03919914c8ced58dfb0afd5ee4fb950bcbbe42ba505f00f75be399ac4a61f7a7eb612b58051bc78ae245b7b122f760e4\"}" + "event_json": "{\"id\":\"5e6db69a9c9968a8f1eb3699ddcf19c0e7b7c9255df616ce7032928b93ad0f6a\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000016,\"kind\":1,\"tags\":[[\"e\",\"3333333333333333333333333333333333333333333333333333333333333333\",\"wss://relay.example\",\"\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"Marked reply with citation\",\"sig\":\"d610d090bab46e06d4a674d4bdfd3204f64bc8d1b94929d64cd9ddfd604de89dc9c5ac87229e2f095091e7cac2805ef2ad45325b019e2a79c89b677981f3b068\"}" }, "expected": { "style": "marked", @@ -394,17 +394,17 @@ "citations": [ { "tag_index": 0, - "raw_tag": ["e", "3333333333333333333333333333333333333333333333333333333333333333", "wss://relay.example", "", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], + "raw_tag": ["e", "3333333333333333333333333333333333333333333333333333333333333333", "wss://relay.example", "", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], "event_id": "3333333333333333333333333333333333333333333333333333333333333333", "relay": "wss://relay.example", - "author_hint": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + "author_hint": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af" } ], "participants": [ { "tag_index": 2, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null } ], @@ -415,7 +415,7 @@ "id": "project_signed_nip10_marked_with_malformed_citation", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"c346aaff3f00a5c8fac4d8dcc15f286f56acbc4608c2e67e799266643f2544fa\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000017,\"kind\":1,\"tags\":[[\"e\",\"3333333333333333333333333333333333333333333333333333333333333333\",\"\",\"mention\"],[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"Marked reply with malformed citation\",\"sig\":\"25d8248ba0220435036611dfbf14c4d52f63a2f29e568f9fd79435faa126d7f862068a1db66dac9a2179911e084eb12a03948a51f0ad7a50ab4fc6a83491037b\"}" + "event_json": "{\"id\":\"19a98ea4c777451618f4f36549abbc352f55c27e254978a2a0dcc0c910cc52ce\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000017,\"kind\":1,\"tags\":[[\"e\",\"3333333333333333333333333333333333333333333333333333333333333333\",\"\",\"mention\"],[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"Marked reply with malformed citation\",\"sig\":\"8fbb467df2771e7a6fc67ca12bfefa2e5b635bfe16d8b963df29d7d8a8df3387e7f9229677045317e470247656db8c87261dc1cf38580c1856b32b2a4fb5791c\"}" }, "expected": { "style": "marked", @@ -433,8 +433,8 @@ "participants": [ { "tag_index": 2, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null } ], @@ -451,7 +451,7 @@ "id": "project_signed_nip10_marked_nested_reordered", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"8179bf853f4b24f4ba7af58f162c0dabf08e74c2fe27df4e5573e48d86a8c1c5\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000002,\"kind\":1,\"tags\":[[\"e\",\"2222222222222222222222222222222222222222222222222222222222222222\",\"wss://parent.relay.example\",\"reply\",\"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\"],[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"wss://root.relay.example\",\"root\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"],[\"p\",\"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"Nested reply\",\"sig\":\"53b88d556d28f98b43ee36eb8b6453d1fa36da7058891100608ab8e0842dc3d1c49de29323f08679ecbee9e49cf3a09c59139c9e7285826dc7db479dd6219fd3\"}" + "event_json": "{\"id\":\"be4126cc38031f6d47a3d00c81d281999fb4dc6e73ae4bf4b757271be5b0abc0\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000002,\"kind\":1,\"tags\":[[\"e\",\"2222222222222222222222222222222222222222222222222222222222222222\",\"wss://parent.relay.example\",\"reply\",\"1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c\"],[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"wss://root.relay.example\",\"root\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"p\",\"1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"Nested reply\",\"sig\":\"4e8439d145b4ce2366818fa6f0722e23bf664c92dbf10728fbad3c223d38150ef160566854e052172ff8c060f8924d030bd24c32919967b6f131771c1376e590\"}" }, "expected": { "style": "marked", @@ -459,30 +459,30 @@ "direct": false, "root": { "tag_index": 1, - "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "wss://root.relay.example", "root", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], + "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "wss://root.relay.example", "root", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], "event_id": "1111111111111111111111111111111111111111111111111111111111111111", "relay": "wss://root.relay.example", - "author_hint": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + "author_hint": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af" }, "parent": { "tag_index": 0, - "raw_tag": ["e", "2222222222222222222222222222222222222222222222222222222222222222", "wss://parent.relay.example", "reply", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"], + "raw_tag": ["e", "2222222222222222222222222222222222222222222222222222222222222222", "wss://parent.relay.example", "reply", "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c"], "event_id": "2222222222222222222222222222222222222222222222222222222222222222", "relay": "wss://parent.relay.example", - "author_hint": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + "author_hint": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c" }, "citations": [], "participants": [ { "tag_index": 2, - "raw_tag": ["p", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"], - "pubkey": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "raw_tag": ["p", "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c"], + "pubkey": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c", "relay": null }, { "tag_index": 3, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null } ], @@ -493,7 +493,7 @@ "id": "project_signed_nip10_positional_direct", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"802da76963580d5932a400a2e56e73caccb80c78d43845c62f5fd95feee600e8\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000003,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"Legacy direct reply\",\"sig\":\"9a1a958170b2faf3c467bf174e776f7f61bf886644657cc12d92d6a9782db89f273508e1d940412645bbb73a6ce7948b7d20daa77647aa5fd8f9e164159826e7\"}" + "event_json": "{\"id\":\"a7141da919755d6ace9b5fa400928d512b4ef785c0ec03d55989bc2d6cbce860\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000003,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"Legacy direct reply\",\"sig\":\"eb2112223ed35f4b0919578a4981e08b403779391f6f9a831ea51763779028d85f72ce8224b1ae469ad6baea21d1d275210bb438a126b4391dab0c347051917a\"}" }, "expected": { "style": "legacy_positional", @@ -511,8 +511,8 @@ "participants": [ { "tag_index": 1, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null } ], @@ -523,7 +523,7 @@ "id": "project_signed_nip10_positional_many", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"71af1b702a370218eeb1d6d4fd4734c8cd5fbc64c02ef90196365bda0755490b\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000004,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"wss://root.relay.example\"],[\"e\",\"3333333333333333333333333333333333333333333333333333333333333333\"],[\"e\",\"2222222222222222222222222222222222222222222222222222222222222222\",\"wss://parent.relay.example\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"],[\"p\",\"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\"]],\"content\":\"Legacy nested reply\",\"sig\":\"49d2bf6c65edab401f7d981bf7bd87b7b1ece61d347f75270f38cf67597791f4058c6bd58444a52f831b0cd15c1f91e18958b3ca877a196ababd7055247d65aa\"}" + "event_json": "{\"id\":\"d3f1220f5cb9d51a76cf2551d27cbbb7cfbb5f68ad221045118eb1fd313c9d64\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000004,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"wss://root.relay.example\"],[\"e\",\"3333333333333333333333333333333333333333333333333333333333333333\"],[\"e\",\"2222222222222222222222222222222222222222222222222222222222222222\",\"wss://parent.relay.example\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"p\",\"1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c\"]],\"content\":\"Legacy nested reply\",\"sig\":\"41a3c1da0c331dc67b1a79eb440dee86b1e6baf11f54fd8e1771ebacb0c0681500d5eece1933fa3c68ca745d552a97753378acac06ce5a7328da0086387f5c59\"}" }, "expected": { "style": "legacy_positional", @@ -555,14 +555,14 @@ "participants": [ { "tag_index": 3, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null }, { "tag_index": 4, - "raw_tag": ["p", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"], - "pubkey": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "raw_tag": ["p", "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c"], + "pubkey": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c", "relay": null } ], @@ -573,7 +573,7 @@ "id": "project_signed_nip10_positional_direct_with_author_hint", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"ff050a31d73546d609080281ad2c1e98f878aba826108e7ee0462cf6b397a941\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000018,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"wss://root.relay.example\",\"\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"Legacy direct with author hint\",\"sig\":\"e71bcb61d49862cd7fa1c776e4fe51aa9e4198234ee93efeacc9afc3d7038c00dee246f1df19eb0fd22aee0a70436708faec39e92bee16e86601f1c91fee1117\"}" + "event_json": "{\"id\":\"f885bad6dc41077036097e81bedb19a0b6b78a48cee24513eb788a997353802c\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000018,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"wss://root.relay.example\",\"\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"Legacy direct with author hint\",\"sig\":\"473111ec136bcf38035a1848c6fa02ac2ba2a946c3270485d93c11287a3ebb0ac87e6a90b1b91d8beb4f8f958a2b58a3cf494622eafad8fb91cb1fdf5f64bcd0\"}" }, "expected": { "style": "legacy_positional", @@ -581,18 +581,18 @@ "direct": true, "root": { "tag_index": 0, - "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "wss://root.relay.example", "", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], + "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "wss://root.relay.example", "", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], "event_id": "1111111111111111111111111111111111111111111111111111111111111111", "relay": "wss://root.relay.example", - "author_hint": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + "author_hint": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af" }, "parent": null, "citations": [], "participants": [ { "tag_index": 1, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null } ], @@ -603,7 +603,7 @@ "id": "project_signed_nip10_positional_many_with_author_hints", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"2473084e4272dc675f34e18b9b2aaa3a164e3132bf19056c734759c922acafa7\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000019,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"wss://root.relay.example\",\"\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"],[\"e\",\"3333333333333333333333333333333333333333333333333333333333333333\",\"wss://citation.relay.example\",\"\",\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\"],[\"e\",\"2222222222222222222222222222222222222222222222222222222222222222\",\"wss://parent.relay.example\",\"\",\"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"],[\"p\",\"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\"],[\"p\",\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\"]],\"content\":\"Legacy nested with author hints\",\"sig\":\"e94c18ae8d2c8785a32f42dfff57712508018e2820d24497fbafcfcecc50890d19a4c15d48b2729c4f9dbe73e4c985e055097174b4505ed3a68858d4d56f7809\"}" + "event_json": "{\"id\":\"1f8d3d805ead850160ed74b446aadca7f5f44591484e1cdb22b471e5d689ece3\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000019,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"wss://root.relay.example\",\"\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"e\",\"3333333333333333333333333333333333333333333333333333333333333333\",\"wss://citation.relay.example\",\"\",\"5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4\"],[\"e\",\"2222222222222222222222222222222222222222222222222222222222222222\",\"wss://parent.relay.example\",\"\",\"1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"p\",\"1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c\"],[\"p\",\"5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4\"]],\"content\":\"Legacy nested with author hints\",\"sig\":\"6c927cc43a95f998ae43956c8e6bc0ab7c18e70dd91eef66ed8360dead902a83c921134e826100b13ea04122ca4bcdf3b0250b0852307141f0a0ed193e87fd9f\"}" }, "expected": { "style": "legacy_positional", @@ -611,44 +611,44 @@ "direct": false, "root": { "tag_index": 0, - "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "wss://root.relay.example", "", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], + "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "wss://root.relay.example", "", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], "event_id": "1111111111111111111111111111111111111111111111111111111111111111", "relay": "wss://root.relay.example", - "author_hint": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + "author_hint": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af" }, "parent": { "tag_index": 2, - "raw_tag": ["e", "2222222222222222222222222222222222222222222222222222222222222222", "wss://parent.relay.example", "", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"], + "raw_tag": ["e", "2222222222222222222222222222222222222222222222222222222222222222", "wss://parent.relay.example", "", "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c"], "event_id": "2222222222222222222222222222222222222222222222222222222222222222", "relay": "wss://parent.relay.example", - "author_hint": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + "author_hint": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c" }, "citations": [ { "tag_index": 1, - "raw_tag": ["e", "3333333333333333333333333333333333333333333333333333333333333333", "wss://citation.relay.example", "", "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"], + "raw_tag": ["e", "3333333333333333333333333333333333333333333333333333333333333333", "wss://citation.relay.example", "", "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4"], "event_id": "3333333333333333333333333333333333333333333333333333333333333333", "relay": "wss://citation.relay.example", - "author_hint": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd" + "author_hint": "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4" } ], "participants": [ { "tag_index": 3, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null }, { "tag_index": 4, - "raw_tag": ["p", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"], - "pubkey": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "raw_tag": ["p", "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c"], + "pubkey": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c", "relay": null }, { "tag_index": 5, - "raw_tag": ["p", "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"], - "pubkey": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "raw_tag": ["p", "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4"], + "pubkey": "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4", "relay": null } ], @@ -659,7 +659,7 @@ "id": "project_signed_nip10_positional_malformed_middle_citation", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"ce7684655dafc04bcb8048f4ba95da4b4780316ce90143c332ca4ed40af60ac7\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000020,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\"],[\"e\",\"3333333333333333333333333333333333333333333333333333333333333333\",\"\",\"mention\"],[\"e\",\"2222222222222222222222222222222222222222222222222222222222222222\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"],[\"p\",\"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\"]],\"content\":\"Legacy nested with malformed citation\",\"sig\":\"a278e44d6c44fe196c3557d01a99ec3cf3eaa31e16b66370743183db671eac6da75f11151b9da194582b03f529c4e9f871cf743d58dea430d0d12c3ed90c4997\"}" + "event_json": "{\"id\":\"6ea3acdf3d4df0e0dc107a514c1801f658ff44345d1c300ab12f553aaeddb40e\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000020,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\"],[\"e\",\"3333333333333333333333333333333333333333333333333333333333333333\",\"\",\"mention\"],[\"e\",\"2222222222222222222222222222222222222222222222222222222222222222\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"p\",\"1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c\"]],\"content\":\"Legacy nested with malformed citation\",\"sig\":\"261e5b2c9632cab25a308b86011655a82dbcda58c4b1908fe8f6465eebf9f250c00086927d9ddf93b73d24467c6e18774bc1b1ffe08a47342b287d86cd2a2b15\"}" }, "expected": { "style": "legacy_positional", @@ -683,14 +683,14 @@ "participants": [ { "tag_index": 3, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null }, { "tag_index": 4, - "raw_tag": ["p", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"], - "pubkey": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "raw_tag": ["p", "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c"], + "pubkey": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c", "relay": null } ], @@ -707,7 +707,7 @@ "id": "project_signed_nip10_precedes_ask_and_media", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"7911ed2e9e2e08173a357f5f83fcdc415ca0c87e95682bad28cefe3a616f5be3\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000005,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"],[\"t\",\"radroots-ask\"],[\"imeta\",\"url https://media.example/image.webp\",\"x malformed\"]],\"content\":\"Reply with compatibility metadata\",\"sig\":\"9bd6c5f40c8587893b3460a53931c1253b2764c44922b25ffb64fe3e96e7fe2b8d139d5fca5ffd7b6f5a1cf19598c2a34e7ab48f5d15b18e695a5e39c81fc9f4\"}" + "event_json": "{\"id\":\"cc9440768dea0bf58b002ace8c836893ac6c7a522bdf25048fa34a6a55c03a4a\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000005,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"t\",\"radroots-ask\"],[\"imeta\",\"url https://media.example/image.webp\",\"x malformed\"]],\"content\":\"Reply with compatibility metadata\",\"sig\":\"e28dd20ed2d04aac40f67a8cccdd6d8cb261fa54c04c1ea57d021d4d4ab9a3c48ca5e52c5c182f4204302315ee9903f39c90117558457a84daeef2505f240294\"}" }, "expected": { "style": "marked", @@ -725,8 +725,8 @@ "participants": [ { "tag_index": 1, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null } ], @@ -737,7 +737,7 @@ "id": "project_signed_nip10_invalid_relay", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"15e0f001e760eb1ac3fd15b8a85e43a5c07603d4ceccdc6ccb93e6cc1876a626\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000006,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"https://relay.example\",\"root\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"Invalid relay\",\"sig\":\"18065b4433c33b29a06ecec64f0f863482479aec2832fcde3c95d2814b5ed91310fdd44df507f346e0231206be239ed4ac85353fc60a838435ae10feae2cc7c6\"}" + "event_json": "{\"id\":\"85b05a80dd168098ea8dcdc6dfa656bcca902120f82bf36a5a5b94c1c949e122\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000006,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"https://relay.example\",\"root\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"Invalid relay\",\"sig\":\"de303499d4cee838d854be0001e686529eda96d37a7f9886f469bf49ad2269aea4b4d3671a1ca820996ba597eece5915d42fdf98452d19bcc630312b0b63f56e\"}" }, "expected": { "style": "marked", @@ -755,8 +755,8 @@ "participants": [ { "tag_index": 1, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null } ], @@ -773,7 +773,7 @@ "id": "project_signed_nip10_canonical_relay_authorities", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"a9f7683ed2eaf63e64af15dddf726ea32ec86e6079cd1038edf379c2de96a199\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000020,\"kind\":1,\"tags\":[[\"e\",\"3333333333333333333333333333333333333333333333333333333333333333\",\"wss://relay.example/nostr/v1?region=ca-bc&next=%2Ffeed\",\"\",\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\"],[\"e\",\"2222222222222222222222222222222222222222222222222222222222222222\",\"ws://127.0.0.1:21003\",\"reply\",\"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\"],[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"wss://[2001:db8::1]:8443/nostr\",\"root\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"ws://localhost:21003\"],[\"p\",\"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\",\"wss://participant.relay.example?region=ca-bc\"],[\"p\",\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\"]],\"content\":\"Canonical relay authorities\",\"sig\":\"4b1691d3d3abcb62a70041da50a0c9790871454a2fb234bac6061a97b4407f91299e905210792c1005883a800d31a7580a218172b4c8ac2834e2c6bcf5b0d925\"}" + "event_json": "{\"id\":\"e7166651c6bd2fd462f7820fca73690049ee9a589eaf161495b38c9b5fe34f92\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000020,\"kind\":1,\"tags\":[[\"e\",\"3333333333333333333333333333333333333333333333333333333333333333\",\"wss://relay.example/nostr/v1?region=ca-bc&next=%2Ffeed\",\"\",\"5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4\"],[\"e\",\"2222222222222222222222222222222222222222222222222222222222222222\",\"ws://127.0.0.1:21003\",\"reply\",\"1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c\"],[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"wss://[2001:db8::1]:8443/nostr\",\"root\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\",\"ws://localhost:21003\"],[\"p\",\"1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c\",\"wss://participant.relay.example?region=ca-bc\"],[\"p\",\"5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4\"]],\"content\":\"Canonical relay authorities\",\"sig\":\"b0faf3e55b6309077108e9e97425d5ea850cbcf5f8b73ad1bbf85731c549ab482dc7dca2cfd7f89a3e1ddd0f1ae8d243e07523ac5251310b0c685cfe0134d073\"}" }, "expected": { "style": "marked", @@ -781,44 +781,44 @@ "direct": false, "root": { "tag_index": 2, - "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "wss://[2001:db8::1]:8443/nostr", "root", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], + "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "wss://[2001:db8::1]:8443/nostr", "root", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], "event_id": "1111111111111111111111111111111111111111111111111111111111111111", "relay": "wss://[2001:db8::1]:8443/nostr", - "author_hint": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + "author_hint": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af" }, "parent": { "tag_index": 1, - "raw_tag": ["e", "2222222222222222222222222222222222222222222222222222222222222222", "ws://127.0.0.1:21003", "reply", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"], + "raw_tag": ["e", "2222222222222222222222222222222222222222222222222222222222222222", "ws://127.0.0.1:21003", "reply", "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c"], "event_id": "2222222222222222222222222222222222222222222222222222222222222222", "relay": "ws://127.0.0.1:21003", - "author_hint": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + "author_hint": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c" }, "citations": [ { "tag_index": 0, - "raw_tag": ["e", "3333333333333333333333333333333333333333333333333333333333333333", "wss://relay.example/nostr/v1?region=ca-bc&next=%2Ffeed", "", "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"], + "raw_tag": ["e", "3333333333333333333333333333333333333333333333333333333333333333", "wss://relay.example/nostr/v1?region=ca-bc&next=%2Ffeed", "", "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4"], "event_id": "3333333333333333333333333333333333333333333333333333333333333333", "relay": "wss://relay.example/nostr/v1?region=ca-bc&next=%2Ffeed", - "author_hint": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd" + "author_hint": "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4" } ], "participants": [ { "tag_index": 3, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "ws://localhost:21003"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "ws://localhost:21003"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": "ws://localhost:21003" }, { "tag_index": 4, - "raw_tag": ["p", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "wss://participant.relay.example?region=ca-bc"], - "pubkey": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "raw_tag": ["p", "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c", "wss://participant.relay.example?region=ca-bc"], + "pubkey": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c", "relay": "wss://participant.relay.example?region=ca-bc" }, { "tag_index": 5, - "raw_tag": ["p", "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"], - "pubkey": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "raw_tag": ["p", "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4"], + "pubkey": "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4", "relay": null } ], @@ -829,7 +829,7 @@ "id": "project_signed_nip10_malformed_relay_authorities", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"715bf99c903fcc3ff2f78411de07df916ab6b4476142c4f6974cf5eeddcabfd5\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000021,\"kind\":1,\"tags\":[[\"e\",\"3333333333333333333333333333333333333333333333333333333333333333\",\"wss://%\",\"\",\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\"],[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"wss://%zz\",\"root\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"],[\"e\",\"2222222222222222222222222222222222222222222222222222222222222222\",\"wss://256.1.1.1\",\"reply\",\"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"wss://[v1.foo]\"],[\"p\",\"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\"],[\"p\",\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\"]],\"content\":\"Malformed relay authorities\",\"sig\":\"37644f8a4b353d758aa1ce78f78fd17c702c4fd862b0408c3c61000ef9533150dc4888ef78b1023f6ee26b0abe786e31e9cc442f62c12260af04750b58f3f20e\"}" + "event_json": "{\"id\":\"fe9fbccea1eb7daf0b7fe3bce5507c5973617b82e8134f2fab82c726bf421ef3\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000021,\"kind\":1,\"tags\":[[\"e\",\"3333333333333333333333333333333333333333333333333333333333333333\",\"wss://%\",\"\",\"5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4\"],[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"wss://%zz\",\"root\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"e\",\"2222222222222222222222222222222222222222222222222222222222222222\",\"wss://256.1.1.1\",\"reply\",\"1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\",\"wss://[v1.foo]\"],[\"p\",\"1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c\"],[\"p\",\"5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4\"]],\"content\":\"Malformed relay authorities\",\"sig\":\"9b179c47c13301bfe31f1d0027dcca7dabf1ebdcb0a0e6f7764cb767c346963c8b801549716f4422e22b8d9311c1bb840faa7751c651e1ad0746f76953617a95\"}" }, "expected": { "style": "marked", @@ -837,44 +837,44 @@ "direct": false, "root": { "tag_index": 1, - "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "wss://%zz", "root", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], + "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "wss://%zz", "root", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], "event_id": "1111111111111111111111111111111111111111111111111111111111111111", "relay": null, - "author_hint": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + "author_hint": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af" }, "parent": { "tag_index": 2, - "raw_tag": ["e", "2222222222222222222222222222222222222222222222222222222222222222", "wss://256.1.1.1", "reply", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"], + "raw_tag": ["e", "2222222222222222222222222222222222222222222222222222222222222222", "wss://256.1.1.1", "reply", "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c"], "event_id": "2222222222222222222222222222222222222222222222222222222222222222", "relay": null, - "author_hint": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + "author_hint": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c" }, "citations": [ { "tag_index": 0, - "raw_tag": ["e", "3333333333333333333333333333333333333333333333333333333333333333", "wss://%", "", "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"], + "raw_tag": ["e", "3333333333333333333333333333333333333333333333333333333333333333", "wss://%", "", "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4"], "event_id": "3333333333333333333333333333333333333333333333333333333333333333", "relay": null, - "author_hint": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd" + "author_hint": "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4" } ], "participants": [ { "tag_index": 3, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "wss://[v1.foo]"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "wss://[v1.foo]"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null }, { "tag_index": 4, - "raw_tag": ["p", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"], - "pubkey": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "raw_tag": ["p", "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c"], + "pubkey": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c", "relay": null }, { "tag_index": 5, - "raw_tag": ["p", "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"], - "pubkey": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "raw_tag": ["p", "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4"], + "pubkey": "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4", "relay": null } ], @@ -882,22 +882,22 @@ { "code": "reply_reference_relay_ignored", "tag_index": 0, - "raw_tag": ["e", "3333333333333333333333333333333333333333333333333333333333333333", "wss://%", "", "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"] + "raw_tag": ["e", "3333333333333333333333333333333333333333333333333333333333333333", "wss://%", "", "5d3eab6e78eb7e467a9e196a63456c9fafb93fb88b7052b83229870889923aa4"] }, { "code": "reply_reference_relay_ignored", "tag_index": 1, - "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "wss://%zz", "root", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"] + "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "wss://%zz", "root", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"] }, { "code": "reply_reference_relay_ignored", "tag_index": 2, - "raw_tag": ["e", "2222222222222222222222222222222222222222222222222222222222222222", "wss://256.1.1.1", "reply", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"] + "raw_tag": ["e", "2222222222222222222222222222222222222222222222222222222222222222", "wss://256.1.1.1", "reply", "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c"] }, { "code": "reply_author_relay_ignored", "tag_index": 3, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "wss://[v1.foo]"] + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "wss://[v1.foo]"] } ] } @@ -906,7 +906,7 @@ "id": "project_signed_nip10_ambiguous_same_reference", "kind": "social.reply.project_verified_event.invalid", "input": { - "event_json": "{\"id\":\"86f19437493f84ecd999d1cd5890ff53fa157b99309f65c056de48e82a8c75bf\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000007,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"reply\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"Ambiguous\",\"sig\":\"730b282fadf78838f6dad8830711fff6cff5b6da0d3c42db49faf1ef547cf3908ec0c901e1ac7069f8c346e9ec73cea879830a8687e18d87e476a1e0f82a0ca7\"}" + "event_json": "{\"id\":\"8642b1d2380d0a52c13011863530f781da7654c37f8176645abf2eb08d39d24d\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000007,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"reply\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"Ambiguous\",\"sig\":\"1f61730dda3b1d00ff2f85701f3e928bfdbd9f1dff8ab2c0971413e03194718c1bba766e62738074ad245d2fae23ebeec2cd3ab45eb353dd82a116833139de42\"}" }, "expected": { "error": "reply_reference_ambiguous" @@ -945,7 +945,7 @@ "id": "project_signed_nip10_invalid_event_id", "kind": "social.reply.project_verified_event.invalid", "input": { - "event_json": "{\"id\":\"2c071cfb2696c8cb2e676564290007bcbc995d08a5404462f747d6ceb73194fe\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000009,\"kind\":1,\"tags\":[[\"e\",\"not-an-event-id\",\"\",\"root\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"Invalid event id\",\"sig\":\"712bed9b975b2742dbb4b241e70893c67fbd4debab110c7d44bf365500405cc9c5c39efa1f9a3260a3a57f10cd0b981d84c327ff4ae0f1afa21c6e9fc8f8b851\"}" + "event_json": "{\"id\":\"8847b627c9e8e07a6506fcd66e2db952b76d12128498093f149f7b166400b3d0\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000009,\"kind\":1,\"tags\":[[\"e\",\"not-an-event-id\",\"\",\"root\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"Invalid event id\",\"sig\":\"83e1bf2c28e54ef653d52b352f9f41693030f50e105d4d67027df357187e84343ab44ceb039e09c3e93806692a4b670a94f00e407eb86d86b9af20d5c92f5602\"}" }, "expected": { "error": "reply_event_id_invalid" @@ -955,7 +955,7 @@ "id": "project_signed_nip10_author_hint_mismatch", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"a54d89f21c0a80df592eab60b07b0800ea5bd212fbe17d0f9deb852c109775a9\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000010,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"],[\"p\",\"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\"]],\"content\":\"Author mismatch\",\"sig\":\"3a9b2af22a1b63a1bf6a4cdf0f83497a199ff6f5edc5b1ea9fd0a70c4dd12034431e3992be9ee80827cd0f396e70d0a9f0c316408a269c80949cb5a0cf59c5f7\"}" + "event_json": "{\"id\":\"24e1807536ffe4dcdb01267f6eca1e53bf34c3e2d20a13111b864d5af8b14c43\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000010,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"],[\"p\",\"1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c\"]],\"content\":\"Author mismatch\",\"sig\":\"ae4be83e55311c831de6e47fb070b42bd92632010eca8f045519fddccdb029ebfbe8e7a4d58885522d1a4fc18cb43c6e3f5db8ecb6a11ec5f536e3a3a74c5c61\"}" }, "expected": { "style": "marked", @@ -963,18 +963,18 @@ "direct": true, "root": { "tag_index": 0, - "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "", "root", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], + "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "", "root", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], "event_id": "1111111111111111111111111111111111111111111111111111111111111111", "relay": null, - "author_hint": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + "author_hint": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af" }, "parent": null, "citations": [], "participants": [ { "tag_index": 1, - "raw_tag": ["p", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"], - "pubkey": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "raw_tag": ["p", "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c"], + "pubkey": "1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c", "relay": null } ], @@ -982,7 +982,7 @@ { "code": "reply_author_mismatch_ignored", "tag_index": 0, - "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "", "root", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"] + "raw_tag": ["e", "1111111111111111111111111111111111111111111111111111111111111111", "", "root", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"] } ] } @@ -991,7 +991,7 @@ "id": "project_signed_nip10_blank_content", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"bb57163b91910e28747d2ea50c89a84fc4d72ce0509d87e97492518f71081d39\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000013,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"\",\"sig\":\"b1833129fc7568362e5c308a3d4b44b09c5d7b7c474b1335cb9a332e9167689678c009547f312b5bc79442bd018ed8ed2af6c64eafd3112bb96e154d6b7b4b48\"}" + "event_json": "{\"id\":\"399f0d0258c1546392643f1fab84fa4ee5fc6cfaf28608f6dff48c027c1f1ec4\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000013,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"\",\"sig\":\"d0409197aa610b8febfea4fb527355b8f43021298c272cd1978a5f9e3edd75d2f08a6cc96fa32d2a3b70026a0403b285813231558cf8cddaffd0a1a3bf8426c7\"}" }, "expected": { "style": "marked", @@ -1009,8 +1009,8 @@ "participants": [ { "tag_index": 1, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null } ], @@ -1021,7 +1021,7 @@ "id": "project_signed_nip10_invalid_author_hint_tolerated", "kind": "social.reply.project_verified_event.valid", "input": { - "event_json": "{\"id\":\"64a50435d0e23c12ae6e52b0eddcd0e9a8efb07f0c59e2b41f839a30b9593d56\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000014,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\",\"not-a-pubkey\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"Malformed optional author\",\"sig\":\"3a554dd47779861e5c020bdcad2103b4831eaf7930b8a801bb99d7c0bcd898ef1a4a79aa8a3856533ab1b88bed0b2a8c44afafa6118daf8b172d502e22eeb95f\"}" + "event_json": "{\"id\":\"d4d58ea56554e78570dc2d75507b1211879002d69b902787b02e93b864315c09\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000014,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\",\"not-a-pubkey\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"Malformed optional author\",\"sig\":\"072e5c49445db582f80620d45e07836bd76860de7b347c48259bc94d718b04b89c02cce87dee6e32b27137a218b7fe0a387856e81b6268bf8bcb3fe0e5ab2f9f\"}" }, "expected": { "style": "marked", @@ -1039,8 +1039,8 @@ "participants": [ { "tag_index": 1, - "raw_tag": ["p", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], - "pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "raw_tag": ["p", "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"], + "pubkey": "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af", "relay": null } ], @@ -1086,7 +1086,7 @@ "id": "project_signed_nip10_lone_reply_marker", "kind": "social.reply.project_verified_event.invalid", "input": { - "event_json": "{\"id\":\"eb5f2eea6aa74ffcbd758cb5fb72749babcad7343717cb30caac19200154f03a\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000011,\"kind\":1,\"tags\":[[\"e\",\"2222222222222222222222222222222222222222222222222222222222222222\",\"\",\"reply\"],[\"p\",\"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\"]],\"content\":\"Lone reply\",\"sig\":\"b4f2d2a564f248fc7012e427a1fea9267de728342485c3f8a4f19066cd15e4295b14a51f7aab898d38e61a5c86d134a80863e6ae1394081b4d9e368dee65e94b\"}" + "event_json": "{\"id\":\"e5822b15847a9952e156f9c46b3e1a3673da63e6ed72035a9088722c3bbfa3df\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000011,\"kind\":1,\"tags\":[[\"e\",\"2222222222222222222222222222222222222222222222222222222222222222\",\"\",\"reply\"],[\"p\",\"1952b8c6943898bceffcff1b7699c4a775a4d13b4a9ba0096ba26ef04492bb1c\"]],\"content\":\"Lone reply\",\"sig\":\"0b4f90ad15407fd37119ae1e6c34e9c00c200790735fe457c19f53a45576a5cd444fd1506bd0e4d3b5ad50c1905e4022cc901ae74de42d78e5f68d018ac6f977\"}" }, "expected": { "error": "reply_marker_count" @@ -1096,7 +1096,7 @@ "id": "project_signed_nip10_unknown_marker", "kind": "social.reply.project_verified_event.invalid", "input": { - "event_json": "{\"id\":\"266e800a1a46fefad41fd745d3750eac53e5527339be4aa0b28f0fb8ebe34bea\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000012,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"mention\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"Unknown marker\",\"sig\":\"fd06119aad71aef0851c900fed068540ca6dde40ccfb8fc70c74cf8d10f0fdd13aac49863753fa8f1fd679c1890ba410259a291780682cc3f8fcf5b89e381afe\"}" + "event_json": "{\"id\":\"69f5cd728b45ee3688d949c318c4b46a1a7320d8f700b289339e537235007968\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000012,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"mention\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"Unknown marker\",\"sig\":\"52a5d203bd422ba9c2962093d09bdf03d8fd02eaa5ab4eb518888e1fcf9db7a13e6d305e356baa1a6edf36f9752cc1830c9d7f9493d705fad6655e5d580571f5\"}" }, "expected": { "error": "reply_marker_missing" @@ -1106,7 +1106,7 @@ "id": "admit_signed_nip10_marked_direct", "kind": "social.reply.verify_and_admit_event.valid", "input": { - "event_json": "{\"id\":\"2340fc3fec291f4d4429bf13bf23cc3b7ec8589aa5e6426a5fc5a25bfcf1a896\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000001,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"Direct reply\",\"sig\":\"16afb66cf2e30450a1055d697044b0f27835352553f32f7ac8d18387cc27861dfde3bb820a8882c00f933c13d4c967df5d5db986cc228a80dd3d291841bf08cd\"}" + "event_json": "{\"id\":\"d62b9340ac9808fc84a751788d017344ede91aea1c89081be3f7bff4a2266354\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000001,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"Direct reply\",\"sig\":\"206758bee31328a53457e3190b046a4a184941223f4e8ed1696db28d71c9af03138fe9add32d5e97d6f3b50bd0f78e4d5a91629dbf4d12aedd4315ce96c97e8c\"}" }, "expected": { "contract_id": "radroots.social.reply.v1", @@ -1118,7 +1118,7 @@ "id": "admit_signed_nip10_positional_direct", "kind": "social.reply.verify_and_admit_event.valid", "input": { - "event_json": "{\"id\":\"802da76963580d5932a400a2e56e73caccb80c78d43845c62f5fd95feee600e8\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000003,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"Legacy direct reply\",\"sig\":\"9a1a958170b2faf3c467bf174e776f7f61bf886644657cc12d92d6a9782db89f273508e1d940412645bbb73a6ce7948b7d20daa77647aa5fd8f9e164159826e7\"}" + "event_json": "{\"id\":\"a7141da919755d6ace9b5fa400928d512b4ef785c0ec03d55989bc2d6cbce860\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000003,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"Legacy direct reply\",\"sig\":\"eb2112223ed35f4b0919578a4981e08b403779391f6f9a831ea51763779028d85f72ce8224b1ae469ad6baea21d1d275210bb438a126b4391dab0c347051917a\"}" }, "expected": { "contract_id": "radroots.social.reply.v1", @@ -1130,7 +1130,7 @@ "id": "admit_signed_nip10_invalid_signature", "kind": "social.reply.verify_and_admit_event.invalid", "input": { - "event_json": "{\"id\":\"2340fc3fec291f4d4429bf13bf23cc3b7ec8589aa5e6426a5fc5a25bfcf1a896\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000001,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"p\",\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"]],\"content\":\"Direct reply\",\"sig\":\"06afb66cf2e30450a1055d697044b0f27835352553f32f7ac8d18387cc27861dfde3bb820a8882c00f933c13d4c967df5d5db986cc228a80dd3d291841bf08cd\"}" + "event_json": "{\"id\":\"d62b9340ac9808fc84a751788d017344ede91aea1c89081be3f7bff4a2266354\",\"pubkey\":\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"created_at\":1781000001,\"kind\":1,\"tags\":[[\"e\",\"1111111111111111111111111111111111111111111111111111111111111111\",\"\",\"root\"],[\"p\",\"e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af\"]],\"content\":\"Direct reply\",\"sig\":\"006758bee31328a53457e3190b046a4a184941223f4e8ed1696db28d71c9af03138fe9add32d5e97d6f3b50bd0f78e4d5a91629dbf4d12aedd4315ce96c97e8c\"}" }, "expected": { "error": "signature_invalid" diff --git a/crates/event_codec/tests/fixtures/profile_verified_event.v1.json b/crates/event_codec/tests/fixtures/profile_verified_event.v1.json @@ -4,12 +4,12 @@ "vectors": [ { "expected": { - "event_id": "a07878757d705d3cd848b9264791d699069068a5f0a575112f351367b0987958", + "event_id": "407b62d3d2c91737c4cba8352ec844b2c5cdd2c9dd441edd93a3c70cdbf8d7e7", "kind": 65535 }, "id": "event_verify_max_kind_001", "input": { - "event_json": "{\"id\":\"a07878757d705d3cd848b9264791d699069068a5f0a575112f351367b0987958\",\"pubkey\":\"1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f\",\"created_at\":1800000104,\"kind\":65535,\"tags\":[],\"content\":\"maximum-kind\",\"sig\":\"d79b19843a0bfd769c02c73866d44a3a06f7b11e107a5257971b60e700aa25565802fd3a7eed4042fe8db7d709a465e5f61478eb8291178831bf48f6b0980671\"}" + "event_json": "{\"id\":\"407b62d3d2c91737c4cba8352ec844b2c5cdd2c9dd441edd93a3c70cdbf8d7e7\",\"pubkey\":\"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df\",\"created_at\":1800000104,\"kind\":65535,\"tags\":[],\"content\":\"maximum-kind\",\"sig\":\"d1791afa8b3428151e6d6c8425842bcc68ebbce202bb6abb24976ad514794f8df5b4602cf69eee26fb20b7afcb249fb7a0eac5c953839838bccdb03bd1212ab6\"}" }, "kind": "event.verify_nip01.valid" }, @@ -19,7 +19,7 @@ }, "id": "event_verify_id_mismatch_001", "input": { - "event_json": "{\"content\":\"{\\\"display_name\\\":\\\"Moss Street Farm\\\",\\\"bot\\\":false,\\\"website\\\":\\\"https://mossstreet.example\\\",\\\"picture\\\":42}\",\"created_at\":1800000100,\"id\":\"fdcebf1cbdcddea8027b5e214cb7b223fa662d8b85f5d68acf2e8849be0d71c4\",\"kind\":0,\"pubkey\":\"1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f\",\"sig\":\"e5448d11671bcf73aa8d56941aff9df46d4e9fb250596671950e5f3c9d747440523efd33d8b9ff4f2a2ef1bd4b79e0a7cf5850132172b1db4b642ef2b348f721\",\"tags\":[]}" + "event_json": "{\"content\":\"{\\\"display_name\\\":\\\"Moss Street Farm\\\",\\\"bot\\\":false,\\\"website\\\":\\\"https://mossstreet.example\\\",\\\"picture\\\":42}\",\"created_at\":1800000100,\"id\":\"062bee187e9e645b81ec26ade05a69b5e8398caf527be8de0d9a45311ed0c7a0\",\"kind\":0,\"pubkey\":\"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df\",\"sig\":\"4290da0bb6422986647bc8cd5f63bd52d49f41e7b665d3b47105b8109183e8d596f322c531d4061df53e1d2b70fda12d5d1c14f3720d7a56d9d0a03746af5109\",\"tags\":[]}" }, "kind": "event.verify_nip01.invalid_id" }, @@ -29,19 +29,19 @@ }, "id": "event_verify_signature_invalid_001", "input": { - "event_json": "{\"content\":\"{\\\"display_name\\\":\\\"Moss Street Farm\\\",\\\"bot\\\":false,\\\"website\\\":\\\"https://mossstreet.example\\\",\\\"picture\\\":42}\",\"created_at\":1800000100,\"id\":\"b0450c4fb0a82cc829159646f90dc548503e8b7f850a434fd9ea58bf1b8d677f\",\"kind\":0,\"pubkey\":\"1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f\",\"sig\":\"d015e365c530c44fbc33e970af13616e482fafe65d0947edcdaa1e7b3038e9285b4b6826bdf454e8381d66e9dc6978d9974358572d97850ebc726fcc539e2b88\",\"tags\":[]}" + "event_json": "{\"content\":\"{\\\"display_name\\\":\\\"Moss Street Farm\\\",\\\"bot\\\":false,\\\"website\\\":\\\"https://mossstreet.example\\\",\\\"picture\\\":42}\",\"created_at\":1800000100,\"id\":\"762bee187e9e645b81ec26ade05a69b5e8398caf527be8de0d9a45311ed0c7a0\",\"kind\":0,\"pubkey\":\"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df\",\"sig\":\"0290da0bb6422986647bc8cd5f63bd52d49f41e7b665d3b47105b8109183e8d596f322c531d4061df53e1d2b70fda12d5d1c14f3720d7a56d9d0a03746af5109\",\"tags\":[]}" }, "kind": "event.verify_nip01.invalid_signature" }, { "expected": { - "error": "malformed_envelope" + "error": "invalid_public_key" }, "id": "event_verify_malformed_curve_pubkey_001", "input": { "event_json": "{\"id\":\"8d71bc1e4126e8b16c7e9229487d9028df9508c156d5e501d1487eda799af161\",\"pubkey\":\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\",\"created_at\":1800000107,\"kind\":0,\"tags\":[],\"content\":\"malformed-curve-pubkey\",\"sig\":\"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}" }, - "kind": "event.verify_nip01.malformed_envelope" + "kind": "event.wire.invalid_public_key" }, { "expected": { @@ -50,13 +50,13 @@ }, "id": "event_verify_kind_overflow_001", "input": { - "event_json": "{\"content\":\"overflow-kind\",\"created_at\":1800000106,\"id\":\"82dff74958bd7e1e52ad98add08bbb70d4ce9cf9d90e4741c64c212df0804ccb\",\"kind\":65536,\"pubkey\":\"1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f\",\"sig\":\"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"tags\":[]}" + "event_json": "{\"content\":\"overflow-kind\",\"created_at\":1800000106,\"id\":\"ecb111a334b5d374db240f42c32fd57ce61f42d4bbe1c1d88b62ed72755f906c\",\"kind\":65536,\"pubkey\":\"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df\",\"sig\":\"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"tags\":[]}" }, "kind": "event.verify_nip01.kind_overflow" }, { "expected": { - "event_id": "b0450c4fb0a82cc829159646f90dc548503e8b7f850a434fd9ea58bf1b8d677f", + "event_id": "762bee187e9e645b81ec26ade05a69b5e8398caf527be8de0d9a45311ed0c7a0", "projected": { "bot": false, "display_name": "Moss Street Farm" @@ -69,7 +69,7 @@ }, "id": "profile_admit_tagless_tolerant_001", "input": { - "event_json": "{\"id\":\"b0450c4fb0a82cc829159646f90dc548503e8b7f850a434fd9ea58bf1b8d677f\",\"pubkey\":\"1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f\",\"created_at\":1800000100,\"kind\":0,\"tags\":[],\"content\":\"{\\\"display_name\\\":\\\"Moss Street Farm\\\",\\\"bot\\\":false,\\\"website\\\":\\\"https://mossstreet.example\\\",\\\"picture\\\":42}\",\"sig\":\"e5448d11671bcf73aa8d56941aff9df46d4e9fb250596671950e5f3c9d747440523efd33d8b9ff4f2a2ef1bd4b79e0a7cf5850132172b1db4b642ef2b348f721\"}" + "event_json": "{\"id\":\"762bee187e9e645b81ec26ade05a69b5e8398caf527be8de0d9a45311ed0c7a0\",\"pubkey\":\"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df\",\"created_at\":1800000100,\"kind\":0,\"tags\":[],\"content\":\"{\\\"display_name\\\":\\\"Moss Street Farm\\\",\\\"bot\\\":false,\\\"website\\\":\\\"https://mossstreet.example\\\",\\\"picture\\\":42}\",\"sig\":\"4290da0bb6422986647bc8cd5f63bd52d49f41e7b665d3b47105b8109183e8d596f322c531d4061df53e1d2b70fda12d5d1c14f3720d7a56d9d0a03746af5109\"}" }, "kind": "profile.verify_and_admit.valid" }, @@ -80,7 +80,7 @@ }, "id": "profile_admit_wrong_kind_001", "input": { - "event_json": "{\"id\":\"05b2ebdf444f09330198f8c07ea3e3c7d8ac97d94c41e957b74bce921f611080\",\"pubkey\":\"1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f\",\"created_at\":1800000102,\"kind\":1,\"tags\":[],\"content\":\"{\\\"name\\\":\\\"not-a-profile\\\"}\",\"sig\":\"3d12c2dfea5cff7e9993166d20b9092f4a6a9dd7e9f4af26355d2f4c4fa0e1ba7a0e5fe6e4b90c93ae57d52cc71b38b409051702200868dfd601dbdd74b89710\"}" + "event_json": "{\"id\":\"530131615015d1631d89c80e5cbde5487ce44de24d1164e7d9d8be86f47f1399\",\"pubkey\":\"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df\",\"created_at\":1800000102,\"kind\":1,\"tags\":[],\"content\":\"{\\\"name\\\":\\\"not-a-profile\\\"}\",\"sig\":\"1e62c75d7cd1427ce03728ebc27413c284a9c72a0c1049ea6e537ccf7f1a3ed139718468c3f0cf78dc2da7d22ccf35843463272d8f42f59bccd69ffebb8ef3bf\"}" }, "kind": "profile.verify_and_admit.invalid_kind" }, @@ -90,19 +90,19 @@ }, "id": "profile_admit_non_object_001", "input": { - "event_json": "{\"id\":\"671f2d9f80a2fa2759c9514ae36fd18296cee71417fc86995525f2c659a5f781\",\"pubkey\":\"1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f\",\"created_at\":1800000103,\"kind\":0,\"tags\":[],\"content\":\"[]\",\"sig\":\"67d0420384e366407499ce4ab501cd87a02bea0d4221007b7a3ff01d9b68a0b9d372882184ab48775a8516f6a6554b506fc3e7652162a53e08a43e63daeacac7\"}" + "event_json": "{\"id\":\"6205ecbaead32e5bb64afa301446f3ba9cf47d3113b23db6978800f47e5e4183\",\"pubkey\":\"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df\",\"created_at\":1800000103,\"kind\":0,\"tags\":[],\"content\":\"[]\",\"sig\":\"909f64b7b5393a80e7db8d0aa788d301133f966c23346e71ca9c019f8b7ac297fe7e27b5049410d60f5858c9060bc7e86fcf8b165c53da2c45f200a00b03f98f\"}" }, "kind": "profile.verify_and_admit.invalid_metadata" }, { "expected": { "created_at": 1800000105, - "event_id": "ad00fc208cc7036b95fadb7a4660bc600aa007502430250630d70d15b50695b3" + "event_id": "73956f3c723129dbe43ec2865261f6de04632b2817daede8b3cc47ab93faac3f" }, "id": "profile_equal_time_lowest_id_001", "input": { - "first_event_json": "{\"id\":\"fdcebf1cbdcddea8027b5e214cb7b223fa662d8b85f5d68acf2e8849be0d71c4\",\"pubkey\":\"1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f\",\"created_at\":1800000105,\"kind\":0,\"tags\":[],\"content\":\"{\\\"name\\\":\\\"arrival-a\\\"}\",\"sig\":\"445a4a08bd365acbe3d68b1433cd8952f8974cb1f454c7d6790881b123c1e7a6449662f78e3044436c7cda8745ae74aa8ee382e292160a3a3f420dd3bb4f275c\"}", - "second_event_json": "{\"id\":\"ad00fc208cc7036b95fadb7a4660bc600aa007502430250630d70d15b50695b3\",\"pubkey\":\"1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f\",\"created_at\":1800000105,\"kind\":0,\"tags\":[],\"content\":\"{\\\"name\\\":\\\"arrival-b\\\"}\",\"sig\":\"6b52cb1cbcf2639104b564144517d8479833272690514af9e9d45b170a1c88320ac3425b9339aa525e591584f97666b1c556b4709fb6ef27959775e70c8caabe\"}" + "first_event_json": "{\"id\":\"73956f3c723129dbe43ec2865261f6de04632b2817daede8b3cc47ab93faac3f\",\"pubkey\":\"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df\",\"created_at\":1800000105,\"kind\":0,\"tags\":[],\"content\":\"{\\\"name\\\":\\\"arrival-a\\\"}\",\"sig\":\"18c2196e1f9eba23147f138f2ee2e5b140bbfc48ec37f72f4919c28d2d03eaeb60269fe7c6d61a8d93f5d25e05a94f5f87dc1a449850b239114bb7fe76cd6190\"}", + "second_event_json": "{\"id\":\"e6e8ff39b7e4365d8fd89a8d47fb6c4e33ce364a449aeb108d5219b4f5d23658\",\"pubkey\":\"585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df\",\"created_at\":1800000105,\"kind\":0,\"tags\":[],\"content\":\"{\\\"name\\\":\\\"arrival-b\\\"}\",\"sig\":\"0b87cc548732f65032187fe33e1f357fd8fe4d1d4c6ec3a2ee8e42713f6bfa73c12f2e6740374ec11b1f318d78c07730dc495abbe50ba025dfbe697041297a22\"}" }, "kind": "profile.select_equal_time_head" } diff --git a/crates/event_codec/tests/job_traits.rs b/crates/event_codec/tests/job_traits.rs @@ -14,7 +14,7 @@ use radroots_event_codec::job::traits::{BorrowedEventAdapter, JobEventLike}; use test_fixtures::{FIXTURE_ALICE_PUBLIC_KEY_HEX, RELAY_PRIMARY_WSS}; const EVENT_ID: &str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; -const AUTHOR: &str = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; +const AUTHOR: &str = "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df"; const EVENT_SIG: &str = concat!( "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" @@ -67,7 +67,7 @@ fn borrowed_event_adapter_builds_request_metadata() { let metadata = adapter.to_job_request_metadata().unwrap(); assert_eq!(metadata.id, event.id_str()); - assert_eq!(metadata.author, event.author_str()); + assert_eq!(metadata.author, event.author().to_hex()); assert_eq!(metadata.published_at, event.created_at_u64()); assert_eq!(metadata.kind, event.kind_u32()); assert_eq!(metadata.data, req); @@ -134,7 +134,7 @@ fn borrowed_event_adapter_builds_request_metadata_and_index() { let index = adapter.to_job_request_event_index().unwrap(); assert_eq!(index.event.id_str(), event.id_str()); - assert_eq!(index.event.author_str(), event.author_str()); + assert_eq!(index.event.author().to_hex(), event.author().to_hex()); assert_eq!(index.event.created_at_u64(), event.created_at_u64()); assert_eq!(index.event.kind_u32(), event.kind_u32()); assert_eq!(index.event.content(), event.content()); @@ -151,7 +151,7 @@ fn borrowed_event_adapter_builds_result_metadata_and_index() { let adapter = BorrowedEventAdapter::new(&event, event.created_at_u64(), &tags, event.sig_str()); let metadata = adapter.to_job_result_metadata().unwrap(); assert_eq!(metadata.id, event.id_str()); - assert_eq!(metadata.author, event.author_str()); + assert_eq!(metadata.author, event.author().to_hex()); assert_eq!(metadata.published_at, event.created_at_u64()); assert_eq!(metadata.kind, event.kind_u32()); assert_eq!(metadata.data.kind, result.kind); @@ -160,7 +160,7 @@ fn borrowed_event_adapter_builds_result_metadata_and_index() { let index = adapter.to_job_result_event_index().unwrap(); assert_eq!(index.event.id_str(), event.id_str()); - assert_eq!(index.event.author_str(), event.author_str()); + assert_eq!(index.event.author().to_hex(), event.author().to_hex()); assert_eq!(index.event.created_at_u64(), event.created_at_u64()); assert_eq!(index.event.kind_u32(), event.kind_u32()); assert_eq!(index.event.content(), event.content()); @@ -177,7 +177,7 @@ fn borrowed_event_adapter_builds_feedback_metadata_and_index() { let adapter = BorrowedEventAdapter::new(&event, event.created_at_u64(), &tags, event.sig_str()); let metadata = adapter.to_job_feedback_metadata().unwrap(); assert_eq!(metadata.id, event.id_str()); - assert_eq!(metadata.author, event.author_str()); + assert_eq!(metadata.author, event.author().to_hex()); assert_eq!(metadata.published_at, event.created_at_u64()); assert_eq!(metadata.kind, event.kind_u32()); assert_eq!(metadata.data.kind, feedback.kind); @@ -186,7 +186,7 @@ fn borrowed_event_adapter_builds_feedback_metadata_and_index() { let index = adapter.to_job_feedback_event_index().unwrap(); assert_eq!(index.event.id_str(), event.id_str()); - assert_eq!(index.event.author_str(), event.author_str()); + assert_eq!(index.event.author().to_hex(), event.author().to_hex()); assert_eq!(index.event.created_at_u64(), event.created_at_u64()); assert_eq!(index.event.kind_u32(), event.kind_u32()); assert_eq!(index.event.content(), event.content()); diff --git a/crates/event_codec/tests/knowledge.rs b/crates/event_codec/tests/knowledge.rs @@ -93,7 +93,7 @@ fn event_with_parts( ) -> RadrootsEventEnvelope { RadrootsEventEnvelope::new(RadrootsEventEnvelopeParts { id: event.id_str().to_string(), - author: event.author_str().to_string(), + author: event.author().to_hex().to_string(), created_at: event.created_at_u64(), kind: event.kind_u32(), tags, diff --git a/crates/event_codec/tests/knowledge_fixtures.rs b/crates/event_codec/tests/knowledge_fixtures.rs @@ -90,7 +90,7 @@ fn event_with_parts( ) -> RadrootsEventEnvelope { RadrootsEventEnvelope::new(RadrootsEventEnvelopeParts { id: event.id_str().to_string(), - author: event.author_str().to_string(), + author: event.author().to_hex().to_string(), created_at: event.created_at_u64(), kind: event.kind_u32(), tags, diff --git a/crates/event_codec/tests/message.rs b/crates/event_codec/tests/message.rs @@ -273,7 +273,7 @@ fn message_metadata_and_index_from_event_roundtrip() { let index = parsed_from_event( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa".to_string(), - "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb".to_string(), + test_fixtures::FIXTURE_ALICE_PUBLIC_KEY_HEX.to_string(), 77, KIND_MESSAGE, "hello".to_string(), diff --git a/crates/event_codec/tests/operational_listing.rs b/crates/event_codec/tests/operational_listing.rs @@ -37,7 +37,7 @@ use std::{borrow::Cow, collections::BTreeSet, fs, path::Path, str::FromStr}; use serde_json::Value; const EVENT_ID: &str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; -const AUTHOR: &str = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; +const AUTHOR: &str = "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df"; const EVENT_SIG: &str = concat!( "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" @@ -1148,7 +1148,7 @@ fn listing_parsed_wrappers_preserve_event_metadata() { ) .unwrap(); assert_eq!(parsed.event.id_str(), EVENT_ID); - assert_eq!(parsed.event.author_str(), AUTHOR); + assert_eq!(parsed.event.author().to_hex(), AUTHOR); assert_eq!(parsed.event.created_at_u64(), 7); assert_eq!(parsed.event.sig_str(), EVENT_SIG); assert_eq!(parsed.data.data.d_tag, listing.d_tag); diff --git a/crates/event_codec/tests/profile.rs b/crates/event_codec/tests/profile.rs @@ -13,6 +13,8 @@ use radroots_event_codec::profile::decode::{ data_from_event, parsed_from_event, profile_from_content, }; +const AUTHOR: &str = "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df"; + #[test] fn profile_from_content_parses_bot_boolean() { let content = r#"{"name":"alice","bot":true}"#; @@ -184,7 +186,7 @@ fn profile_metadata_ignores_short_unknown_and_unrelated_profile_type_tags() { fn profile_parsed_event_preserves_wire_event_and_decoded_data() { let parsed = parsed_from_event( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa".to_string(), - "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb".to_string(), + AUTHOR.to_string(), 42, KIND_PROFILE, "{\"name\":\"alice\"}".to_string(), @@ -204,10 +206,7 @@ fn profile_parsed_event_preserves_wire_event_and_decoded_data() { parsed.event.id_str(), "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ); - assert_eq!( - parsed.event.author_str(), - "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" - ); + assert_eq!(parsed.event.author().to_hex(), AUTHOR); assert_eq!(parsed.event.created_at_u64(), 42); assert_eq!(parsed.event.kind_u32(), KIND_PROFILE); assert_eq!(parsed.event.content(), "{\"name\":\"alice\"}"); diff --git a/crates/event_codec/tests/report.rs b/crates/event_codec/tests/report.rs @@ -18,7 +18,7 @@ use radroots_event_codec::{ }; const EVENT_ID: &str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; -const REPORTED: &str = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; +const REPORTED: &str = "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df"; const FILE_HASH: &str = "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"; const ARTICLE_D_TAG: &str = "DDDDDDDDDDDDDDDDDDDDDA"; diff --git a/crates/event_codec/tests/repost.rs b/crates/event_codec/tests/repost.rs @@ -23,7 +23,7 @@ use radroots_event_codec::{ }; const EVENT_ID: &str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; -const AUTHOR: &str = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; +const AUTHOR: &str = "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df"; const EVENT_SIG: &str = concat!( "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" diff --git a/crates/event_codec/tests/structured_decode.rs b/crates/event_codec/tests/structured_decode.rs @@ -574,7 +574,7 @@ fn plot_metadata_and_index_decode_roundtrip() { EVENT_SIG.to_string(), ) .expect("plot index"); - assert_eq!(index.event.author_str(), TEST_PUBKEY_HEX); + assert_eq!(index.event.author().to_hex(), TEST_PUBKEY_HEX); assert_eq!(index.data.data.d_tag, d_tag); } diff --git a/crates/event_codec/tests/verified_comment_conformance.rs b/crates/event_codec/tests/verified_comment_conformance.rs @@ -346,7 +346,7 @@ fn authored_comment( object_optional_str(root, "relay", &vector.id), )?; assert_eq!( - root_reference.author().as_str(), + root_reference.author().to_hex(), object_str(root, "author", &vector.id), "{} declared address author drifted", vector.id @@ -449,7 +449,7 @@ fn projection_snapshot(projection: &RadrootsInboundNip22CommentProjection) -> Va "kind_raw_tag": root.kind_raw_tag(), "kind": root.kind().as_u32(), "relay": root.relay().map(|relay| relay.as_str()), - "author_hint": root.author_hint().map(|author| author.as_str()), + "author_hint": root.author_hint().map(|author| author.to_hex()), "author": participant_snapshot(root.author()), "raw_tag": root.raw_tag(), }), @@ -475,7 +475,7 @@ fn projection_snapshot(projection: &RadrootsInboundNip22CommentProjection) -> Va "kind_raw_tag": reference.kind_raw_tag(), "kind": reference.kind(), "relay": reference.relay().map(|relay| relay.as_str()), - "author_hint": reference.author_hint().map(|author| author.as_str()), + "author_hint": reference.author_hint().map(|author| author.to_hex()), "author": participant_snapshot(reference.author()), "raw_tag": reference.raw_tag(), }, @@ -511,7 +511,7 @@ fn projection_snapshot(projection: &RadrootsInboundNip22CommentProjection) -> Va "kind_raw_tag": parent.kind_raw_tag(), "kind": parent.kind(), "relay": parent.relay().map(|relay| relay.as_str()), - "author_hint": parent.author_hint().map(|author| author.as_str()), + "author_hint": parent.author_hint().map(|author| author.to_hex()), "author": participant_snapshot(parent.author()), "raw_tag": parent.raw_tag(), }, @@ -543,7 +543,7 @@ fn projection_snapshot(projection: &RadrootsInboundNip22CommentProjection) -> Va fn participant_snapshot(participant: &RadrootsInboundNip22Participant) -> Value { json!({ "tag_index": participant.tag_index(), - "pubkey": participant.pubkey().as_str(), + "pubkey": participant.pubkey().to_hex(), "relay": participant.relay().map(|relay| relay.as_str()), "raw_tag": participant.raw_tag(), }) diff --git a/crates/event_codec/tests/verified_deletion_conformance.rs b/crates/event_codec/tests/verified_deletion_conformance.rs @@ -765,7 +765,7 @@ fn projection_snapshot(projection: &RadrootsInboundNip09DeletionProjection) -> V "tag_index": target.tag_index(), "coordinate": target.coordinate().as_str(), "kind": target.coordinate().kind(), - "pubkey": target.coordinate().pubkey().as_str(), + "pubkey": target.coordinate().pubkey().to_hex(), "identifier": target.coordinate().identifier(), "raw_tag": target.raw_tag(), })).collect::<Vec<_>>(), diff --git a/crates/event_codec/tests/verified_post_conformance.rs b/crates/event_codec/tests/verified_post_conformance.rs @@ -583,7 +583,7 @@ fn reply_event_reference_value(reference: &RadrootsInboundNip10EventReference) - "raw_tag": reference.raw_tag(), "event_id": reference.event_id().as_str(), "relay": reference.relay().map(|relay| relay.as_str()), - "author_hint": reference.author_hint().map(|author| author.as_str()), + "author_hint": reference.author_hint().map(|author| author.to_hex()), }) } @@ -591,7 +591,7 @@ fn reply_participant_value(participant: &RadrootsInboundNip10Participant) -> Val json!({ "tag_index": participant.tag_index(), "raw_tag": participant.raw_tag(), - "pubkey": participant.pubkey().as_str(), + "pubkey": participant.pubkey().to_hex(), "relay": participant.relay().map(|relay| relay.as_str()), }) } diff --git a/crates/event_codec/tests/verified_profile_conformance.rs b/crates/event_codec/tests/verified_profile_conformance.rs @@ -7,6 +7,7 @@ use radroots_event::event_head::{ RadrootsEventHeadDecision, event_head_candidate_for_event, select_event_head, }; use radroots_event::{RadrootsEventEnvelope, RadrootsEventEnvelopeParts, RadrootsNip01EventWire}; +use radroots_event::{RadrootsEventWireError, ids::RadrootsIdParseError}; use radroots_event_codec::profile::admission::{ RadrootsAdmittedProfileEvent, RadrootsProfileAdmissionError, verify_and_admit_profile_event, }; @@ -89,7 +90,7 @@ fn execute(vector: &Vector) { "event.verify_nip01.valid" => verify_valid(vector), "event.verify_nip01.invalid_id" => verify_invalid_id(vector), "event.verify_nip01.invalid_signature" => verify_invalid_signature(vector), - "event.verify_nip01.malformed_envelope" => verify_malformed_envelope(vector), + "event.wire.invalid_public_key" => reject_invalid_wire_public_key(vector), "event.verify_nip01.kind_overflow" => verify_kind_overflow(vector), "profile.verify_and_admit.valid" => profile_admit_valid(vector), "profile.verify_and_admit.invalid_kind" => profile_admit_invalid_kind(vector), @@ -133,11 +134,17 @@ fn verify_invalid_signature(vector: &Vector) { assert_eq!(error, RadrootsNip01VerificationError::SignatureInvalid); } -fn verify_malformed_envelope(vector: &Vector) { - let error = verify_nip01_event(canonical_envelope(input_str(vector, "event_json"))) - .expect_err("invalid secp256k1 public key must fail envelope conversion"); - assert_eq!(error.code(), expected_str(vector, "error")); - assert_eq!(error, RadrootsNip01VerificationError::MalformedEnvelope); +fn reject_invalid_wire_public_key(vector: &Vector) { + let error = RadrootsNip01EventWire::parse_json(input_str(vector, "event_json")) + .expect_err("invalid secp256k1 public key must fail wire parsing"); + assert_eq!(expected_str(vector, "error"), "invalid_public_key"); + assert_eq!( + error, + RadrootsEventWireError::InvalidIdentifier { + field: "pubkey", + error: RadrootsIdParseError::InvalidPublicKey, + } + ); } fn verify_kind_overflow(vector: &Vector) { diff --git a/crates/event_codec/tests/wire.rs b/crates/event_codec/tests/wire.rs @@ -58,7 +58,7 @@ fn draft_validation_accepts_wire_parts_without_signed_envelope() { assert_eq!(draft.kind_u32(), KIND_GEOCHAT); assert_eq!(draft.created_at_u64(), 99); - assert_eq!(draft.expected_pubkey_str(), "a".repeat(64)); + assert_eq!(draft.expected_pubkey().to_hex(), "a".repeat(64)); assert_eq!(draft.content(), "hello"); assert_eq!(draft.tags().len(), 1); assert_eq!(draft.expected_event_id_str().len(), 64); diff --git a/crates/event_store/Cargo.toml b/crates/event_store/Cargo.toml @@ -29,6 +29,10 @@ radroots_event_codec = { workspace = true, default-features = false, features = "serde_json", "std", ] } +radroots_identity = { workspace = true, default-features = false, features = [ + "serde", + "std", +] } radroots_transport = { workspace = true, default-features = false } hex = { workspace = true } getrandom = { workspace = true, optional = true, features = ["std"] } diff --git a/crates/event_store/contracts/food_availability_projection_v1.manifest.json b/crates/event_store/contracts/food_availability_projection_v1.manifest.json @@ -411,8 +411,8 @@ "executor_id": "radroots_event_store.food_availability_projection_v1.result_vector_executor.v1", "executor_path": "crates/event_store/tests/food_availability_projection_v1_result_vector.rs", "executor_test": "food_availability_projection_v1_result_vector", - "executor_byte_length": 34075, - "executor_sha256": "9e8e11abae7bbc7dda30eab6f0a79074ffc3761aa6b955cff58c4c62fa581aa3", + "executor_byte_length": 34078, + "executor_sha256": "59e20d81562299cf9dd942dd637b5ca404c7aacc98c7ce3fbf1e14751c1b2d9b", "executor_hash_algorithm": "sha256_bytes_v1" } } diff --git a/crates/event_store/contracts/food_availability_projection_v1.manifest.sha256 b/crates/event_store/contracts/food_availability_projection_v1.manifest.sha256 @@ -1 +1 @@ -33b93a3c87ce428e8aa6f5e92643c77203d9aa006c53ce96f3562fe6d68ffd23 +02dfe1b450fbdac16e718888215b4dd5c85d8975440fa21e8f439fb24c2b2990 diff --git a/crates/event_store/contracts/source_maintenance_v1.manifest.json b/crates/event_store/contracts/source_maintenance_v1.manifest.json @@ -5,7 +5,7 @@ "manifest_schema": { "path": "crates/event_store/contracts/source_maintenance_v1.manifest.schema.json", "byte_length": 12315, - "sha256": "ad4a6c8ae9488fc8033792bc6952af04687f312901c1847d8c668a62913bb642", + "sha256": "96ea98a5abf3348b61565954cd34f2c622411d8dd34205ef04134bbe0e3d3f2b", "hash_algorithm": "sha256_bytes_v1" }, "predecessor": { @@ -13,7 +13,7 @@ "manifest": { "path": "crates/event_store/contracts/food_availability_projection_v1.manifest.json", "byte_length": 17455, - "sha256": "33b93a3c87ce428e8aa6f5e92643c77203d9aa006c53ce96f3562fe6d68ffd23", + "sha256": "02dfe1b450fbdac16e718888215b4dd5c85d8975440fa21e8f439fb24c2b2990", "hash_algorithm": "sha256_bytes_v1" } }, @@ -23,7 +23,7 @@ "up": { "path": "crates/event_store/migrations/0004_source_maintenance.up.sql", "byte_length": 19841, - "sha256": "425dc799f392b87f265a6fb81f89c4a1c7a5db8391ab0380970708cb9c66704d", + "sha256": "ab2724188f8d08c897eebea2533a635e7c74282a25e84e4c0c37e78b08837a43", "hash_algorithm": "sha256_bytes_v1" }, "down": { @@ -32,7 +32,7 @@ "sha256": "fe44fd53c51545c08ea479b385e6781079dab70fc63da2a3c205d727a00ce860", "hash_algorithm": "sha256_bytes_v1" }, - "schema_sha256": "d526d96ea02be12b4b0aed99e97cfdde17c4474ace67111506a7b900ee78b186", + "schema_sha256": "074f85b663444ac150239ecd8441ea4a96ad83a798a55e22d2e5e2f7ee943a8c", "catalog": { "objects": [ "radroots_event_store_source_capacity_delete_guard", @@ -96,7 +96,7 @@ "nip09_hook_id": "nip09_reconciliation_v1", "nip09_manifest_sha256": "74af832420ffbaa9805e89df3c0b34f126a443e1598f757e3372f407f9003b77", "food_hook_id": "food_availability_projection_v1", - "food_manifest_sha256": "33b93a3c87ce428e8aa6f5e92643c77203d9aa006c53ce96f3562fe6d68ffd23", + "food_manifest_sha256": "02dfe1b450fbdac16e718888215b4dd5c85d8975440fa21e8f439fb24c2b2990", "food_scope_fingerprint_sha256": "8b63c5ddc48a2cc7db69295238b96d5f814dba50427c80b4d0079f061e6d3de0", "active_generation_authority": "radroots_event_store_source_state", "marker_close_authority": "radroots_event_store_source_capacity_marker_close_guard" @@ -206,10 +206,297 @@ "hash_algorithm": "sha256_bytes_v1" }, { + "role": "blossom_hash_authority", + "path": "crates/blossom/src/hash.rs", + "byte_length": 11251, + "sha256": "753eff6ef9a810045c88839d39a46b37d62a4ad0a5ea57aa30e2a8219e3cdbda", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "blossom_url_authority", + "path": "crates/blossom/src/url.rs", + "byte_length": 15364, + "sha256": "05325325da6627ba48318851fb4e61a9ad540aad37fc1c27ac9a47f27300891f", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_contract_facade", + "path": "crates/event/src/contract.rs", + "byte_length": 86, + "sha256": "9994cbca9dcc7450ad133b6b927e7c06bee08ef813652452cc1e56a284c1be10", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_contract_registry_v7_authority", + "path": "crates/event/src/contract/registry_v7.rs", + "byte_length": 155788, + "sha256": "6305e487a6d51c0b04ad5620f28530d550e81b28152406cd5f224563ecd72f5c", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_envelope_authority", + "path": "crates/event/src/envelope.rs", + "byte_length": 31165, + "sha256": "97a3bb38d630666bba497b98e856ee457d6899de230dabf6cab786a5bd55a3ce", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_head_facade", + "path": "crates/event/src/event_head.rs", + "byte_length": 68, + "sha256": "cb52f6006f7ecd862707d6b048f9fc407e0cd5ebcd3091b3c54e195ffa5cba64", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_head_v1_authority", + "path": "crates/event/src/event_head/v1.rs", + "byte_length": 7529, + "sha256": "0a4b50c4b7a93e9d88cc995cf69d9e87b341cba66d7feb51c357dfa4e5b2de37", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_ids_authority", + "path": "crates/event/src/ids.rs", + "byte_length": 46282, + "sha256": "f3c34e7dcf09fc225cb9c12f02ae932d5155c859f73f8b8573db8e5ebf298678", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_trade_authority", + "path": "crates/event/src/trade.rs", + "byte_length": 68376, + "sha256": "1012b44295cb26844206304bc24b355a49c18a023844f6b3905337c63b1417a7", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_kinds_authority", + "path": "crates/event/src/kinds.rs", + "byte_length": 34961, + "sha256": "8b3ce6193cab1f7e1587d0c1b2880a81b0aa43c77d89671b602772db37edcebf", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_tags_authority", + "path": "crates/event/src/tags.rs", + "byte_length": 4530, + "sha256": "cb8f12a639fc72d9238e32495d9e67e928e6627fb8c94ec0a58c5d95e7373cd6", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_draft_authority", + "path": "crates/event/src/draft.rs", + "byte_length": 58674, + "sha256": "fa4e802f1143eba72ba7fc334104ea0d6613c886725ff9f3e61dab2443c243b6", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_calendar_authority", + "path": "crates/event/src/calendar.rs", + "byte_length": 103969, + "sha256": "94e07896e8cf3486b55becf2a64be72a5129625bd52a86e70e2a4b273fcf20e5", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_classified_listing_authority", + "path": "crates/event/src/classified_listing.rs", + "byte_length": 8226, + "sha256": "745aa08953a6243ea1afad22aa63e44f6746f2f243ab0d6b617d6ab64fa58749", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_profile_authority", + "path": "crates/event/src/profile.rs", + "byte_length": 19061, + "sha256": "f2b03be027aea187645e8bc3ae7a7d4004d6e58d4e1b361b35786ccdc36d907a", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_post_authority", + "path": "crates/event/src/post.rs", + "byte_length": 22813, + "sha256": "d4a573cf2510f3a261f6aac3efd16489591281cdbdb387af5a7d67f516e1e056", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_comment_authority", + "path": "crates/event/src/comment.rs", + "byte_length": 36375, + "sha256": "f4d1a57780eff0d315bc4e2fbad316dfb7c7ced1bcc9e8e85afe0b5ecdaf3aa8", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_food_availability_authority", + "path": "crates/event/src/food_availability.rs", + "byte_length": 45680, + "sha256": "1c8c3fba6514f9b246545b3305e8ac2742258857d1b813fa34c5fbefa6135e12", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_deletion_authority", + "path": "crates/event/src/deletion.rs", + "byte_length": 31155, + "sha256": "c8b7ab79998ae62e03497f5511dd3950a41d73155edda3d8d34c65fc797e9d09", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_relay_hint_authority", + "path": "crates/event/src/relay_hint.rs", + "byte_length": 14317, + "sha256": "1a14aea5d2f2620970dc1de9e3d311d9042cab4d5805a56461548168112a0801", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_media_authority", + "path": "crates/event/src/media.rs", + "byte_length": 3821, + "sha256": "ca98ddb134cb522912900544080d910867398d6aff6e8c6b061dc1fb77212ec3", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_social_authority", + "path": "crates/event/src/social.rs", + "byte_length": 5483, + "sha256": "1b89c6d0954822e7f1e778479ed43694e88929bcd5310ee066f8f4ba6505045a", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_wire_facade", + "path": "crates/event/src/wire.rs", + "byte_length": 68, + "sha256": "cb52f6006f7ecd862707d6b048f9fc407e0cd5ebcd3091b3c54e195ffa5cba64", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_wire_v1_authority", + "path": "crates/event/src/wire/v1.rs", + "byte_length": 22133, + "sha256": "cc28c8cbd962b32ed2efe43e84c1e0d1ea3bd89636efff2d5553714072fce1a4", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_codec_verification_facade", + "path": "crates/event_codec/src/verification.rs", + "byte_length": 253, + "sha256": "b49a32df605035c87f295c0a151140d43d2e588c5e11b05183e5fc92993dae0e", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_codec_verification_v1_authority", + "path": "crates/event_codec/src/verification/v1.rs", + "byte_length": 8751, + "sha256": "fc4c5d45e475151c56330ba9c4db70de603e4ec48adabd6365f80d5f6a3733f4", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_codec_registry_v7_admission_authority", + "path": "crates/event_codec/src/admission/registry_v7.rs", + "byte_length": 5350, + "sha256": "755e63dd7ad1115c219e5a3ea540bef67d2770fc9f2a5aa6ba97c925c99bdced", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_codec_profile_inbound_facade", + "path": "crates/event_codec/src/profile/inbound.rs", + "byte_length": 86, + "sha256": "9994cbca9dcc7450ad133b6b927e7c06bee08ef813652452cc1e56a284c1be10", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_codec_profile_registry_v7_authority", + "path": "crates/event_codec/src/profile/inbound/registry_v7.rs", + "byte_length": 10394, + "sha256": "c37c225ea8153beb098a39c4a56203aa03382af12646f40cd3f8628663700702", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_codec_post_inbound_facade", + "path": "crates/event_codec/src/post/inbound.rs", + "byte_length": 86, + "sha256": "9994cbca9dcc7450ad133b6b927e7c06bee08ef813652452cc1e56a284c1be10", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_codec_post_registry_v7_authority", + "path": "crates/event_codec/src/post/inbound/registry_v7.rs", + "byte_length": 16016, + "sha256": "bc0bb839c28f3588f05544c846c987528ea3934c75305fef70af8e027a97cc58", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_codec_reply_inbound_facade", + "path": "crates/event_codec/src/reply/inbound.rs", + "byte_length": 86, + "sha256": "9994cbca9dcc7450ad133b6b927e7c06bee08ef813652452cc1e56a284c1be10", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_codec_reply_registry_v7_authority", + "path": "crates/event_codec/src/reply/inbound/registry_v7.rs", + "byte_length": 26820, + "sha256": "d49a950c25e36fc145ce9f1762ae345c028e6f2834b63795603741bbe365c3c8", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_codec_comment_inbound_facade", + "path": "crates/event_codec/src/comment/inbound.rs", + "byte_length": 86, + "sha256": "9994cbca9dcc7450ad133b6b927e7c06bee08ef813652452cc1e56a284c1be10", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_codec_comment_registry_v7_authority", + "path": "crates/event_codec/src/comment/inbound/registry_v7.rs", + "byte_length": 53783, + "sha256": "30d1b0155963b25d64685ddd042f423ef7707b111dc56ead15bd468e0433a432", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_codec_deletion_facade", + "path": "crates/event_codec/src/deletion/mod.rs", + "byte_length": 115, + "sha256": "17d56f82ddb0a86bc97abbcf3e037fe460ea31fff2548f527be4bf004dac3a95", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_codec_deletion_reconciliation_v1_authority", + "path": "crates/event_codec/src/deletion/reconciliation_v1.rs", + "byte_length": 38469, + "sha256": "3e06d1fa923ca5faabb1e95338c35650b0e20b078ff5c972e35ab845d8b7476c", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_codec_food_inbound_facade", + "path": "crates/event_codec/src/food_availability/inbound.rs", + "byte_length": 86, + "sha256": "9994cbca9dcc7450ad133b6b927e7c06bee08ef813652452cc1e56a284c1be10", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_codec_food_registry_v7_authority", + "path": "crates/event_codec/src/food_availability/inbound/registry_v7.rs", + "byte_length": 26865, + "sha256": "908015346eaec97bee6f44fe2a524410b701529ac19a5dab4505706d40d527da", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_codec_job_traits_authority", + "path": "crates/event_codec/src/job/traits.rs", + "byte_length": 5029, + "sha256": "353df3703de4d99fc318474952dc6c95cbce9a19756f3e235ed2d715f36c4364", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_store_dependency_authority", + "path": "crates/event_store/Cargo.toml", + "byte_length": 1569, + "sha256": "30f43004bcf0ffa9b9b6f338cba8c56be0265bc1cee708e93f7b7dc54ed60f9c", + "hash_algorithm": "sha256_bytes_v1" + }, + { "role": "event_store_error_and_limits", "path": "crates/event_store/src/error.rs", - "byte_length": 19421, - "sha256": "4772e041cb20a4963afb2f3159804c777e2f2be61bfdb6ee267e7a7c04258972", + "byte_length": 19517, + "sha256": "4bf24ee1aa6117597ab467b1379a05549b79024213dc7622a2d276bc26fffab4", "hash_algorithm": "sha256_bytes_v1" }, { @@ -236,15 +523,43 @@ { "role": "predecessor_model_public_surface", "path": "crates/event_store/src/model.rs", - "byte_length": 33617, - "sha256": "79296b8f263aa06d17005795e4515f769f064ea6fd971eeb1296e1151debaf20", + "byte_length": 33596, + "sha256": "98b1742ffb517f66f8e9edefa61d1c3cf3e22be5985202c6c340310a98c72c8e", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_store_reconciliation_v1_model", + "path": "crates/event_store/src/model/reconciliation_v1.rs", + "byte_length": 11138, + "sha256": "8a26bc373035878ef9b41767ceea7b681896e17d88bedce118de1d622125e1d6", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "event_store_reconciliation_v1_ingest_model", + "path": "crates/event_store/src/model/ingest_reconciliation_v1.rs", + "byte_length": 1626, + "sha256": "47bf13b3fc0f8a913a660f7d655413de0f6b90568bc4acc510aa6bd741bab47b", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "addressable_transition_feed_model", + "path": "crates/event_store/src/model/addressable_transition_feed_v1.rs", + "byte_length": 22279, + "sha256": "f8ea454a0e998a3d433bba52d1ff9759a04fcb91db286cf2a2b10ef7d0057694", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "food_projection_model", + "path": "crates/event_store/src/model/food_availability_projection_v1.rs", + "byte_length": 17482, + "sha256": "7e8ead52ebfe091e3770878b781a9d089f2f4273f8f57ca0e5c6b12c3ab9acaf", "hash_algorithm": "sha256_bytes_v1" }, { "role": "source_generation_rebuild_authority", "path": "crates/event_store/src/nip09/reconciliation_v1.rs", - "byte_length": 184407, - "sha256": "c455d40fc736e3db264f567c7809af7bd897d89be8a33dfb21667a6ef6b8d6c6", + "byte_length": 184402, + "sha256": "7fa01e52f51d3470ba60e6068dc05797c2a6eaf5eb317d23111a961dbe4451f9", "hash_algorithm": "sha256_bytes_v1" }, { @@ -257,22 +572,57 @@ { "role": "public_store_and_transaction_authority", "path": "crates/event_store/src/store.rs", - "byte_length": 394574, - "sha256": "db57dc3e35e64c7194683142fe55edba853671a829269449dd2273056dfc3a0e", + "byte_length": 394777, + "sha256": "6a2431a6f4b7b5b1d25f493758008ae2246fbe57472552e233fe259404f629a1", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "addressable_transition_feed_store", + "path": "crates/event_store/src/store/addressable_transition_feed_v1.rs", + "byte_length": 40261, + "sha256": "3b978d2cc7d489b23733d37413824c6fd0bf0c83e3117654939fa856bc8956a3", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "food_projection_store", + "path": "crates/event_store/src/store/food_availability_projection_v1.rs", + "byte_length": 48993, + "sha256": "91003e69bb6d7a82cc200581089d0e9eb61203a2706e9a3d27286e118b069feb", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "predecessor_post_core_v1_extension", + "path": "crates/event_store/src/store/post_core_extensions_v1.rs", + "byte_length": 6923, + "sha256": "2fbfc6252f9ce249468a99b5230fd6b7b59b9e47ee4f38783c5fd9379c823fd0", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "predecessor_post_core_v1_storage", + "path": "crates/event_store/src/store/post_core_storage_v1.rs", + "byte_length": 16876, + "sha256": "f27dc7dcd643762226f8d4df0d297027b384bcf1004277222e978965bc2d40cf", "hash_algorithm": "sha256_bytes_v1" }, { "role": "raw_ingest_capacity_authority", "path": "crates/event_store/src/store/protocol_reconciliation_v1.rs", - "byte_length": 30140, - "sha256": "210112eeaa6975a3b4fbb97d5c52588f8c6d8d07975e531d39737fd11235de51", + "byte_length": 30145, + "sha256": "a8a26763dc39124ab7537fdcc3f89a1f0aa7e1830f4f9dec9ee4057bbb4fd228", + "hash_algorithm": "sha256_bytes_v1" + }, + { + "role": "predecessor_protocol_storage", + "path": "crates/event_store/src/store/protocol_storage_v1.rs", + "byte_length": 10929, + "sha256": "20de4436945bac0d8cbeca0ae6cd95232a92da8cd6be6ae6beacba17fe50d658", "hash_algorithm": "sha256_bytes_v1" }, { "role": "source_maintenance_runtime", "path": "crates/event_store/src/source_maintenance_v1.rs", - "byte_length": 51756, - "sha256": "f8d5b62f0613104aa86658d5bf1baade92c7df83f00ef0cddadd734b9797afca", + "byte_length": 51762, + "sha256": "5db9c9e86fd18a2fcc08dbc3468f373bf39d8948bc6a08936b252a4dda3546e9", "hash_algorithm": "sha256_bytes_v1" }, { @@ -285,29 +635,29 @@ { "role": "predecessor_successor_governance", "path": "tools/xtask/src/contract/food_availability_projection.rs", - "byte_length": 194594, - "sha256": "b859df0608b000f0de53f6543d2dea9501fa9080f57e3fdd8d9e71acf386e0a7", + "byte_length": 194572, + "sha256": "f251b1202c72ae0b63a2f0adee35eb474ba39b9cde7348feee3ab7085d306a11", "hash_algorithm": "sha256_bytes_v1" }, { "role": "transitive_predecessor_membership_governance", "path": "tools/xtask/src/contract/nip09_reconciliation.rs", - "byte_length": 835558, - "sha256": "6218e33cc8445fce59194508f73290e7eea8c91495fbe77a5323b258ef21f4a6", + "byte_length": 835899, + "sha256": "c37bb32405003775ce34e1379d1197b8c6e330fff96a402612c200a1d206cb38", "hash_algorithm": "sha256_bytes_v1" }, { "role": "source_maintenance_governance", "path": "tools/xtask/src/contract/source_maintenance.rs", - "byte_length": 177996, - "sha256": "c309da38f12101d77c4de1caa49ef443252cac6238b49692182851c2cf894bda", + "byte_length": 186734, + "sha256": "0b1d19043d06d6f628f4e92dd11f0b7ec6eb9942ad13a426c5ef78c162b35a6a", "hash_algorithm": "sha256_bytes_v1" }, { "role": "contract_command_authority", "path": "tools/xtask/src/contract.rs", - "byte_length": 500241, - "sha256": "972e2a6b1099267e11d9a34e73fd38b20fc217a3dd79bd9a0f1f060b680ba2ba", + "byte_length": 504371, + "sha256": "0f8de542e17aa2b1475d5ccb7c38cd35c9132a3390f3c9537ef5de29aa68420f", "hash_algorithm": "sha256_bytes_v1" }, { diff --git a/crates/event_store/contracts/source_maintenance_v1.manifest.schema.json b/crates/event_store/contracts/source_maintenance_v1.manifest.schema.json @@ -209,7 +209,7 @@ "const": "source_maintenance" }, "schema_sha256": { - "const": "d526d96ea02be12b4b0aed99e97cfdde17c4474ace67111506a7b900ee78b186" + "const": "074f85b663444ac150239ecd8441ea4a96ad83a798a55e22d2e5e2f7ee943a8c" }, "up": { "$ref": "#/$defs/file" @@ -405,7 +405,7 @@ "const": "food_availability_projection_v1" }, "food_manifest_sha256": { - "const": "33b93a3c87ce428e8aa6f5e92643c77203d9aa006c53ce96f3562fe6d68ffd23" + "const": "02dfe1b450fbdac16e718888215b4dd5c85d8975440fa21e8f439fb24c2b2990" }, "food_scope_fingerprint_sha256": { "const": "8b63c5ddc48a2cc7db69295238b96d5f814dba50427c80b4d0079f061e6d3de0" diff --git a/crates/event_store/contracts/source_maintenance_v1.manifest.sha256 b/crates/event_store/contracts/source_maintenance_v1.manifest.sha256 @@ -1 +1 @@ -e3a56e03726af0db35480e55eab9d3244029673cff07bb9e7e1db185125b0785 +0723ecb4b332777159e2b01e3ac45381a9c3087ef63e0fd0bf00e4bf0499f328 diff --git a/crates/event_store/migrations/0004_source_maintenance.up.sql b/crates/event_store/migrations/0004_source_maintenance.up.sql @@ -553,7 +553,7 @@ WHEN NOT EXISTS ( AND hex(cursor.scope_fingerprint) = '8B63C5DDC48A2CC7DB69295238B96D5F814DBA50427C80B4D0079F061E6D3DE0' AND cursor.hook_manifest_sha256 = - '33b93a3c87ce428e8aa6f5e92643c77203d9aa006c53ce96f3562fe6d68ffd23' + '02dfe1b450fbdac16e718888215b4dd5c85d8975440fa21e8f439fb24c2b2990' AND cursor.last_transition_seq = state.last_transition_seq AND cursor.projected_row_count = ( SELECT COUNT(*) diff --git a/crates/event_store/src/error.rs b/crates/event_store/src/error.rs @@ -55,6 +55,8 @@ pub enum RadrootsEventStoreError { Json(#[from] serde_json::Error), #[error("identifier parse error: {0}")] IdParse(#[from] RadrootsIdParseError), + #[error("identity value parse error: {0}")] + Identity(#[from] radroots_identity::Error), #[error("event wire error: {0}")] EventWire(#[from] RadrootsEventWireError), #[error("signed event error: {0}")] diff --git a/crates/event_store/src/generated/food_availability_projection_manifest.rs b/crates/event_store/src/generated/food_availability_projection_manifest.rs @@ -1,10 +1,10 @@ // @generated by `cargo xtask contract food-availability-projection-manifest --write`; do not edit. #![allow(dead_code)] -pub(crate) const FOOD_AVAILABILITY_PROJECTION_MANIFEST_JSON: &str = "{\n \"schema_version\": 1,\n \"contract_id\": \"radroots_event_store.food_availability_projection_v1\",\n \"hook_id\": \"food_availability_projection_v1\",\n \"manifest_schema\": {\n \"path\": \"crates/event_store/contracts/food_availability_projection_v1.manifest.schema.json\",\n \"byte_length\": 7964,\n \"sha256\": \"39171f6ef872a8d1483bc3d55049df5e0d110d9131c5adb4450b7c418f546910\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n \"predecessor\": {\n \"hook_id\": \"nip09_reconciliation_v1\",\n \"manifest\": {\n \"path\": \"crates/event_store/contracts/nip09_reconciliation_v1.manifest.json\",\n \"byte_length\": 537538,\n \"sha256\": \"74af832420ffbaa9805e89df3c0b34f126a443e1598f757e3372f407f9003b77\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n }\n },\n \"migration\": {\n \"version\": 3,\n \"name\": \"food_availability_projection\",\n \"up\": {\n \"path\": \"crates/event_store/migrations/0003_food_availability_projection.up.sql\",\n \"byte_length\": 23683,\n \"sha256\": \"4e7edfb981b25f76055efc7802ec30b4034eeae9b9c0809ea4ea7c574678748a\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n \"down\": {\n \"path\": \"crates/event_store/migrations/0003_food_availability_projection.down.sql\",\n \"byte_length\": 1755,\n \"sha256\": \"29d663320109d9dd0df6a00b6a53d8d988438d01f7a66960a9d4ba3482ffffb8\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n \"schema_sha256\": \"dd12467e04addcbddb5ea0f386c12a8ac05ef5ebaaf949f24dd2c62745f5aaac\",\n \"catalog\": {\n \"objects\": [\n \"radroots_event_store_addressable_feed_generation_insert\",\n \"radroots_event_store_addressable_feed_integrity_v1\",\n \"radroots_event_store_addressable_feed_transition_insert\",\n \"radroots_event_store_addressable_transition_coordinate_idx\",\n \"radroots_event_store_current_visibility_head_lookup_idx\",\n \"radroots_event_store_current_visibility_v1\",\n \"radroots_event_store_food_availability_author_idx\",\n \"radroots_event_store_food_availability_cursor\",\n \"radroots_event_store_food_availability_cursor_delete_guard\",\n \"radroots_event_store_food_availability_cursor_insert_guard\",\n \"radroots_event_store_food_availability_cursor_update_guard\",\n \"radroots_event_store_food_availability_image\",\n \"radroots_event_store_food_availability_image_delete_guard\",\n \"radroots_event_store_food_availability_image_insert_guard\",\n \"radroots_event_store_food_availability_image_update_guard\",\n \"radroots_event_store_food_availability_projection\",\n \"radroots_event_store_food_availability_projection_delete_guard\",\n \"radroots_event_store_food_availability_projection_insert_guard\",\n \"radroots_event_store_food_availability_projection_update_guard\",\n \"radroots_event_store_food_availability_read_v1\",\n \"radroots_event_store_food_availability_recent_idx\",\n \"radroots_event_store_food_availability_search_delete\",\n \"radroots_event_store_food_availability_search_fts\",\n \"radroots_event_store_food_availability_search_fts_config\",\n \"radroots_event_store_food_availability_search_fts_content\",\n \"radroots_event_store_food_availability_search_fts_data\",\n \"radroots_event_store_food_availability_search_fts_docsize\",\n \"radroots_event_store_food_availability_search_fts_idx\",\n \"radroots_event_store_food_availability_search_insert\",\n \"radroots_event_store_food_availability_status_idx\",\n \"radroots_event_store_nip09_address_target_visibility_lookup_idx\"\n ],\n \"tables\": [\n \"radroots_event_store_addressable_feed_integrity_v1\",\n \"radroots_event_store_food_availability_cursor\",\n \"radroots_event_store_food_availability_image\",\n \"radroots_event_store_food_availability_projection\",\n \"radroots_event_store_food_availability_search_fts\",\n \"radroots_event_store_food_availability_search_fts_config\",\n \"radroots_event_store_food_availability_search_fts_content\",\n \"radroots_event_store_food_availability_search_fts_data\",\n \"radroots_event_store_food_availability_search_fts_docsize\",\n \"radroots_event_store_food_availability_search_fts_idx\"\n ],\n \"fts5_tables\": [\n \"radroots_event_store_food_availability_search_fts\"\n ]\n }\n },\n \"profile\": {\n \"event_contract_registry_version\": 7,\n \"addressable_feed_version\": 1,\n \"projection_version\": 1,\n \"scope_kinds\": [\n 30402\n ],\n \"scope_fingerprint_sha256\": \"8b63c5ddc48a2cc7db69295238b96d5f814dba50427c80b4d0079f061e6d3de0\",\n \"food_contract_id\": \"radroots.food.availability.v1\",\n \"admission_authority\": \"event_contract_registry_v7\",\n \"current_visibility_authority\": \"radroots_event_store_current_visibility_v1\",\n \"post_core_capability\": \"apply_v2\"\n },\n \"registry_inventory\": {\n \"path\": \"contracts/event_store/event_contract_registry_v7.inventory.json\",\n \"byte_length\": 158021,\n \"sha256\": \"91595544310f865bdef064ee760c227c870417a95b87b3e27278f8da74fdddea\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n \"food_profile_vector\": {\n \"path\": \"contracts/conformance/vectors/food_availability/profile.v1.json\",\n \"byte_length\": 90099,\n \"sha256\": \"dede1eb1f682ecd548e8cd3ccb251d298762e504e2588a73528e5f7a5b9eff21\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n \"entry_points\": [\n {\n \"role\": \"registry_v7_admission\",\n \"rust_path\": \"radroots_event_codec::admit_verified_event_registry_v7\"\n },\n {\n \"role\": \"migration_registry\",\n \"rust_path\": \"radroots_event_store::migrations::EVENT_STORE_MIGRATIONS[2]\"\n },\n {\n \"role\": \"migration_apply_hook\",\n \"rust_path\": \"radroots_event_store::schema::apply_migration_hook\"\n },\n {\n \"role\": \"migration_validation_hook\",\n \"rust_path\": \"radroots_event_store::schema::validate_migration_hook_state\"\n },\n {\n \"role\": \"post_core_extension\",\n \"rust_path\": \"radroots_event_store::store::PostCoreExtensionCapabilities::apply_v2\"\n },\n {\n \"role\": \"addressable_transition_feed\",\n \"rust_path\": \"radroots_event_store::RadrootsEventStore::addressable_transition_page_v1\"\n },\n {\n \"role\": \"current_visibility\",\n \"rust_path\": \"radroots_event_store::RadrootsEventStore::current_event_visibility_v1\"\n },\n {\n \"role\": \"event_visibility_batch\",\n \"rust_path\": \"radroots_event_store::RadrootsEventStore::event_visibilities\"\n },\n {\n \"role\": \"projection_lookup\",\n \"rust_path\": \"radroots_event_store::RadrootsEventStore::food_availability_v1\"\n },\n {\n \"role\": \"projection_recent\",\n \"rust_path\": \"radroots_event_store::RadrootsEventStore::recent_food_availability_v1\"\n },\n {\n \"role\": \"projection_search\",\n \"rust_path\": \"radroots_event_store::RadrootsEventStore::search_food_availability_v1\"\n },\n {\n \"role\": \"projection_audit\",\n \"rust_path\": \"radroots_event_store::RadrootsEventStore::audit_food_availability_projection_v1\"\n },\n {\n \"role\": \"result_vector_executor\",\n \"rust_path\": \"food_availability_projection_v1_result_vector\"\n }\n ],\n \"source_files\": [\n {\n \"role\": \"workspace_dependency_authority\",\n \"path\": \"Cargo.toml\",\n \"byte_length\": 10836,\n \"sha256\": \"285532dbb0894204843a832880f136ceac5ee312a3203ff951fb0551fac63ec4\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_store_dependency_authority\",\n \"path\": \"crates/event_store/Cargo.toml\",\n \"byte_length\": 1466,\n \"sha256\": \"9e82d57b64bb7fcf145ee8b919682dd6d788b5503be743d11326f5b882fb2d7e\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"blossom_public_surface\",\n \"path\": \"crates/blossom/src/lib.rs\",\n \"byte_length\": 1335,\n \"sha256\": \"61ebee86f02887c45507bab052686da082f74ae26f23d18ff4019e02c70097bd\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"blossom_sha256_value_object\",\n \"path\": \"crates/blossom/src/hash.rs\",\n \"byte_length\": 11251,\n \"sha256\": \"753eff6ef9a810045c88839d39a46b37d62a4ad0a5ea57aa30e2a8219e3cdbda\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"food_event_contract\",\n \"path\": \"crates/event/src/food_availability.rs\",\n \"byte_length\": 45680,\n \"sha256\": \"1c8c3fba6514f9b246545b3305e8ac2742258857d1b813fa34c5fbefa6135e12\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"food_admission\",\n \"path\": \"crates/event_codec/src/food_availability/admission.rs\",\n \"byte_length\": 5799,\n \"sha256\": \"727ebf8f086c14376aba745a0a02b269115fed01e8ce95f90fdd211b9640f842\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"registry_v7_admission\",\n \"path\": \"crates/event_codec/src/admission/registry_v7.rs\",\n \"byte_length\": 5350,\n \"sha256\": \"755e63dd7ad1115c219e5a3ea540bef67d2770fc9f2a5aa6ba97c925c99bdced\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"registry_v7_food_projection\",\n \"path\": \"crates/event_codec/src/food_availability/inbound/registry_v7.rs\",\n \"byte_length\": 26865,\n \"sha256\": \"908015346eaec97bee6f44fe2a524410b701529ac19a5dab4505706d40d527da\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_store_error_surface\",\n \"path\": \"crates/event_store/src/error.rs\",\n \"byte_length\": 17557,\n \"sha256\": \"ac206fafdc67e4c25f4a2f1bcd38eb34ae224b38aca55894b1a9cc67242d8b1a\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"generated_descriptor_registration\",\n \"path\": \"crates/event_store/src/generated.rs\",\n \"byte_length\": 100,\n \"sha256\": \"ddd71b2245f307cac0c8ef835311d0dd9eb2fdaf9d2a76a6c9dc98e56f4faaec\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"public_surface\",\n \"path\": \"crates/event_store/src/lib.rs\",\n \"byte_length\": 3419,\n \"sha256\": \"d5bc071309fd4ec9e26a3cfe9c0e7c00b5de5b6c248902b888891b39e6780d23\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"migration_registry\",\n \"path\": \"crates/event_store/src/migrations.rs\",\n \"byte_length\": 55541,\n \"sha256\": \"ef62808fe75b5c0704567eecccfe23d0b11ae25d332bc5e38451ea2a446c535a\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"model_registration\",\n \"path\": \"crates/event_store/src/model.rs\",\n \"byte_length\": 33617,\n \"sha256\": \"79296b8f263aa06d17005795e4515f769f064ea6fd971eeb1296e1151debaf20\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"schema_hooks\",\n \"path\": \"crates/event_store/src/schema.rs\",\n \"byte_length\": 97574,\n \"sha256\": \"6d259548559f32e259d3502787ccd4efbd22eebd1406dd7dd68c8f3145411543\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"store_ingest_and_wal_authority\",\n \"path\": \"crates/event_store/src/store.rs\",\n \"byte_length\": 357693,\n \"sha256\": \"8bca94e5c7b26cee60a06ea327fcba385e6cbc51550f1774ef4d0488ffa2727b\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"addressable_transition_feed_model\",\n \"path\": \"crates/event_store/src/model/addressable_transition_feed_v1.rs\",\n \"byte_length\": 22314,\n \"sha256\": \"b1c6b0a68f34459f7e14bd63857596154c0aa3fd02dc6c1661d543bb681324a7\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"current_visibility_model\",\n \"path\": \"crates/event_store/src/model/current_visibility_v1.rs\",\n \"byte_length\": 5691,\n \"sha256\": \"25ec92f45006e2f66f2e1c8b954a021334bb1595b849c4d8529f289d3f7aeb25\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"food_projection_model\",\n \"path\": \"crates/event_store/src/model/food_availability_projection_v1.rs\",\n \"byte_length\": 17493,\n \"sha256\": \"1e5ff9c05a81fda223ed1a27ff18a1b08bcdeaec9047a13fdd577390b3e0fdb9\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"addressable_transition_feed_store\",\n \"path\": \"crates/event_store/src/store/addressable_transition_feed_v1.rs\",\n \"byte_length\": 40253,\n \"sha256\": \"fe23424aa1e6b39f9aba2dfa4470652b26b4990f91204a2bdfe379c03da9b610\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"current_visibility_store\",\n \"path\": \"crates/event_store/src/store/current_visibility_v1.rs\",\n \"byte_length\": 15860,\n \"sha256\": \"8615086e674c30700305debcef11de5b3dbfe5aec735c0f58b4ac11caa518596\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"food_projection_store\",\n \"path\": \"crates/event_store/src/store/food_availability_projection_v1.rs\",\n \"byte_length\": 49029,\n \"sha256\": \"0cec060c50c50d9333e0583e338fe311a1c64a1d586c222e391d8cef685cf871\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"predecessor_protocol_storage\",\n \"path\": \"crates/event_store/src/store/protocol_storage_v1.rs\",\n \"byte_length\": 10975,\n \"sha256\": \"155c74d27eee5db1d6f0f844f9d319604eefbbf640f4b2371ac5d0e370816e50\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"predecessor_active_state_fast_validation\",\n \"path\": \"crates/event_store/src/nip09/reconciliation_v1.rs\",\n \"byte_length\": 183733,\n \"sha256\": \"3bddb664491bd9abe878f5b2441d1230fb188368dae341f3425a2b035211366a\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"post_core_capabilities\",\n \"path\": \"crates/event_store/src/store/post_core_extension_capabilities.rs\",\n \"byte_length\": 1255,\n \"sha256\": \"cb434372156cb7ff31dac392d7095c2e5f44b128fae4e705516d6d000e2e2502\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"post_core_dispatcher\",\n \"path\": \"crates/event_store/src/store/post_core_extension_dispatcher.rs\",\n \"byte_length\": 576,\n \"sha256\": \"df62ee92e9f165502d5e533997a47f533129fd3cffab2d9b2012e2ed22405f48\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"post_core_v2_extension\",\n \"path\": \"crates/event_store/src/store/post_core_extensions_v2.rs\",\n \"byte_length\": 294,\n \"sha256\": \"8dcbc503ed9ea6fb06ed9a2a83b0804d928f9590b5706de25a057ad72c0d38d2\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"post_core_v2_storage\",\n \"path\": \"crates/event_store/src/store/post_core_storage_v2.rs\",\n \"byte_length\": 632,\n \"sha256\": \"4b672770f3c34bf887e4cc949c068cb0c87396cb4af8efb6e13d39aa4e0d973a\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"predecessor_post_core_v1_extension\",\n \"path\": \"crates/event_store/src/store/post_core_extensions_v1.rs\",\n \"byte_length\": 6935,\n \"sha256\": \"fb165704c64d982cf3be0a880c44985be6b375758451e94b2aaaf30881769f18\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"predecessor_post_core_v1_storage\",\n \"path\": \"crates/event_store/src/store/post_core_storage_v1.rs\",\n \"byte_length\": 16871,\n \"sha256\": \"a6dca0884762cec3c32e460d17662ced9d0335f30e79b3d5fdb3461259d3ec19\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n }\n ],\n \"public_api\": [\n \"RADROOTS_ADDRESSABLE_TRANSITION_CURSOR_JSON_MAX_BYTES_V1\",\n \"RADROOTS_ADDRESSABLE_TRANSITION_D_TAG_MAX_BYTES_V1\",\n \"RADROOTS_ADDRESSABLE_TRANSITION_FEED_VERSION_V1\",\n \"RADROOTS_ADDRESSABLE_TRANSITION_PAGE_LIMIT_MAX_V1\",\n \"RADROOTS_ADDRESSABLE_TRANSITION_PAGE_RAW_JSON_MAX_BYTES_V1\",\n \"RADROOTS_ADDRESSABLE_TRANSITION_PAGE_SCAN_MAX_V1\",\n \"RADROOTS_ADDRESSABLE_TRANSITION_SCOPE_KIND_MAX_V1\",\n \"RADROOTS_FOOD_AVAILABILITY_PROJECTION_APPLY_PAGE_LIMIT_V1\",\n \"RADROOTS_FOOD_AVAILABILITY_PROJECTION_VERSION_V1\",\n \"RADROOTS_FOOD_AVAILABILITY_SEARCH_QUERY_MAX_BYTES_V1\",\n \"RADROOTS_FOOD_AVAILABILITY_SEARCH_QUERY_MAX_TERMS_V1\",\n \"RadrootsAddressableTransitionCauseV1\",\n \"RadrootsAddressableTransitionCoordinateV1\",\n \"RadrootsAddressableTransitionCursorV1\",\n \"RadrootsAddressableTransitionEventReferenceV1\",\n \"RadrootsAddressableTransitionOriginV1\",\n \"RadrootsAddressableTransitionPageV1\",\n \"RadrootsAddressableTransitionRawHeadDecisionV1\",\n \"RadrootsAddressableTransitionScopeFingerprintV1\",\n \"RadrootsAddressableTransitionScopeV1\",\n \"RadrootsAddressableTransitionV1\",\n \"RadrootsAddressableTransitionVisibilityV1\",\n \"RadrootsCurrentEventVisibilityV1\",\n \"RadrootsCurrentVisibilityDecisionV1\",\n \"RadrootsFoodAvailabilitySearchQueryV1\",\n \"RadrootsFoodAvailabilityStatusFilterV1\",\n \"RadrootsNip09SuppressionEvidenceV1\",\n \"RadrootsNip09SuppressionOutcome\",\n \"RadrootsNip09SuppressionReason\",\n \"RadrootsStoreProducedCanonicalEventV1\",\n \"RadrootsStoredFoodAvailabilityImageV1\",\n \"RadrootsStoredFoodAvailabilityV1\"\n ],\n \"result_vector\": {\n \"canonical_path\": \"contracts/conformance/vectors/event_store/food_availability_projection.v1.json\",\n \"mirror_path\": \"crates/event_store/tests/fixtures/food_availability_projection.v1.json\",\n \"byte_length\": 103659,\n \"sha256\": \"fca2b71b47736ed04ed1e908823b65b3fc3cf0366cb162128369fe328295bb63\",\n \"hash_algorithm\": \"sha256_bytes_v1\",\n \"executor_id\": \"radroots_event_store.food_availability_projection_v1.result_vector_executor.v1\",\n \"executor_path\": \"crates/event_store/tests/food_availability_projection_v1_result_vector.rs\",\n \"executor_test\": \"food_availability_projection_v1_result_vector\",\n \"executor_byte_length\": 34075,\n \"executor_sha256\": \"9e8e11abae7bbc7dda30eab6f0a79074ffc3761aa6b955cff58c4c62fa581aa3\",\n \"executor_hash_algorithm\": \"sha256_bytes_v1\"\n }\n}\n"; +pub(crate) const FOOD_AVAILABILITY_PROJECTION_MANIFEST_JSON: &str = "{\n \"schema_version\": 1,\n \"contract_id\": \"radroots_event_store.food_availability_projection_v1\",\n \"hook_id\": \"food_availability_projection_v1\",\n \"manifest_schema\": {\n \"path\": \"crates/event_store/contracts/food_availability_projection_v1.manifest.schema.json\",\n \"byte_length\": 7964,\n \"sha256\": \"39171f6ef872a8d1483bc3d55049df5e0d110d9131c5adb4450b7c418f546910\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n \"predecessor\": {\n \"hook_id\": \"nip09_reconciliation_v1\",\n \"manifest\": {\n \"path\": \"crates/event_store/contracts/nip09_reconciliation_v1.manifest.json\",\n \"byte_length\": 537538,\n \"sha256\": \"74af832420ffbaa9805e89df3c0b34f126a443e1598f757e3372f407f9003b77\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n }\n },\n \"migration\": {\n \"version\": 3,\n \"name\": \"food_availability_projection\",\n \"up\": {\n \"path\": \"crates/event_store/migrations/0003_food_availability_projection.up.sql\",\n \"byte_length\": 23683,\n \"sha256\": \"4e7edfb981b25f76055efc7802ec30b4034eeae9b9c0809ea4ea7c574678748a\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n \"down\": {\n \"path\": \"crates/event_store/migrations/0003_food_availability_projection.down.sql\",\n \"byte_length\": 1755,\n \"sha256\": \"29d663320109d9dd0df6a00b6a53d8d988438d01f7a66960a9d4ba3482ffffb8\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n \"schema_sha256\": \"dd12467e04addcbddb5ea0f386c12a8ac05ef5ebaaf949f24dd2c62745f5aaac\",\n \"catalog\": {\n \"objects\": [\n \"radroots_event_store_addressable_feed_generation_insert\",\n \"radroots_event_store_addressable_feed_integrity_v1\",\n \"radroots_event_store_addressable_feed_transition_insert\",\n \"radroots_event_store_addressable_transition_coordinate_idx\",\n \"radroots_event_store_current_visibility_head_lookup_idx\",\n \"radroots_event_store_current_visibility_v1\",\n \"radroots_event_store_food_availability_author_idx\",\n \"radroots_event_store_food_availability_cursor\",\n \"radroots_event_store_food_availability_cursor_delete_guard\",\n \"radroots_event_store_food_availability_cursor_insert_guard\",\n \"radroots_event_store_food_availability_cursor_update_guard\",\n \"radroots_event_store_food_availability_image\",\n \"radroots_event_store_food_availability_image_delete_guard\",\n \"radroots_event_store_food_availability_image_insert_guard\",\n \"radroots_event_store_food_availability_image_update_guard\",\n \"radroots_event_store_food_availability_projection\",\n \"radroots_event_store_food_availability_projection_delete_guard\",\n \"radroots_event_store_food_availability_projection_insert_guard\",\n \"radroots_event_store_food_availability_projection_update_guard\",\n \"radroots_event_store_food_availability_read_v1\",\n \"radroots_event_store_food_availability_recent_idx\",\n \"radroots_event_store_food_availability_search_delete\",\n \"radroots_event_store_food_availability_search_fts\",\n \"radroots_event_store_food_availability_search_fts_config\",\n \"radroots_event_store_food_availability_search_fts_content\",\n \"radroots_event_store_food_availability_search_fts_data\",\n \"radroots_event_store_food_availability_search_fts_docsize\",\n \"radroots_event_store_food_availability_search_fts_idx\",\n \"radroots_event_store_food_availability_search_insert\",\n \"radroots_event_store_food_availability_status_idx\",\n \"radroots_event_store_nip09_address_target_visibility_lookup_idx\"\n ],\n \"tables\": [\n \"radroots_event_store_addressable_feed_integrity_v1\",\n \"radroots_event_store_food_availability_cursor\",\n \"radroots_event_store_food_availability_image\",\n \"radroots_event_store_food_availability_projection\",\n \"radroots_event_store_food_availability_search_fts\",\n \"radroots_event_store_food_availability_search_fts_config\",\n \"radroots_event_store_food_availability_search_fts_content\",\n \"radroots_event_store_food_availability_search_fts_data\",\n \"radroots_event_store_food_availability_search_fts_docsize\",\n \"radroots_event_store_food_availability_search_fts_idx\"\n ],\n \"fts5_tables\": [\n \"radroots_event_store_food_availability_search_fts\"\n ]\n }\n },\n \"profile\": {\n \"event_contract_registry_version\": 7,\n \"addressable_feed_version\": 1,\n \"projection_version\": 1,\n \"scope_kinds\": [\n 30402\n ],\n \"scope_fingerprint_sha256\": \"8b63c5ddc48a2cc7db69295238b96d5f814dba50427c80b4d0079f061e6d3de0\",\n \"food_contract_id\": \"radroots.food.availability.v1\",\n \"admission_authority\": \"event_contract_registry_v7\",\n \"current_visibility_authority\": \"radroots_event_store_current_visibility_v1\",\n \"post_core_capability\": \"apply_v2\"\n },\n \"registry_inventory\": {\n \"path\": \"contracts/event_store/event_contract_registry_v7.inventory.json\",\n \"byte_length\": 158021,\n \"sha256\": \"91595544310f865bdef064ee760c227c870417a95b87b3e27278f8da74fdddea\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n \"food_profile_vector\": {\n \"path\": \"contracts/conformance/vectors/food_availability/profile.v1.json\",\n \"byte_length\": 90099,\n \"sha256\": \"dede1eb1f682ecd548e8cd3ccb251d298762e504e2588a73528e5f7a5b9eff21\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n \"entry_points\": [\n {\n \"role\": \"registry_v7_admission\",\n \"rust_path\": \"radroots_event_codec::admit_verified_event_registry_v7\"\n },\n {\n \"role\": \"migration_registry\",\n \"rust_path\": \"radroots_event_store::migrations::EVENT_STORE_MIGRATIONS[2]\"\n },\n {\n \"role\": \"migration_apply_hook\",\n \"rust_path\": \"radroots_event_store::schema::apply_migration_hook\"\n },\n {\n \"role\": \"migration_validation_hook\",\n \"rust_path\": \"radroots_event_store::schema::validate_migration_hook_state\"\n },\n {\n \"role\": \"post_core_extension\",\n \"rust_path\": \"radroots_event_store::store::PostCoreExtensionCapabilities::apply_v2\"\n },\n {\n \"role\": \"addressable_transition_feed\",\n \"rust_path\": \"radroots_event_store::RadrootsEventStore::addressable_transition_page_v1\"\n },\n {\n \"role\": \"current_visibility\",\n \"rust_path\": \"radroots_event_store::RadrootsEventStore::current_event_visibility_v1\"\n },\n {\n \"role\": \"event_visibility_batch\",\n \"rust_path\": \"radroots_event_store::RadrootsEventStore::event_visibilities\"\n },\n {\n \"role\": \"projection_lookup\",\n \"rust_path\": \"radroots_event_store::RadrootsEventStore::food_availability_v1\"\n },\n {\n \"role\": \"projection_recent\",\n \"rust_path\": \"radroots_event_store::RadrootsEventStore::recent_food_availability_v1\"\n },\n {\n \"role\": \"projection_search\",\n \"rust_path\": \"radroots_event_store::RadrootsEventStore::search_food_availability_v1\"\n },\n {\n \"role\": \"projection_audit\",\n \"rust_path\": \"radroots_event_store::RadrootsEventStore::audit_food_availability_projection_v1\"\n },\n {\n \"role\": \"result_vector_executor\",\n \"rust_path\": \"food_availability_projection_v1_result_vector\"\n }\n ],\n \"source_files\": [\n {\n \"role\": \"workspace_dependency_authority\",\n \"path\": \"Cargo.toml\",\n \"byte_length\": 10836,\n \"sha256\": \"285532dbb0894204843a832880f136ceac5ee312a3203ff951fb0551fac63ec4\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_store_dependency_authority\",\n \"path\": \"crates/event_store/Cargo.toml\",\n \"byte_length\": 1466,\n \"sha256\": \"9e82d57b64bb7fcf145ee8b919682dd6d788b5503be743d11326f5b882fb2d7e\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"blossom_public_surface\",\n \"path\": \"crates/blossom/src/lib.rs\",\n \"byte_length\": 1335,\n \"sha256\": \"61ebee86f02887c45507bab052686da082f74ae26f23d18ff4019e02c70097bd\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"blossom_sha256_value_object\",\n \"path\": \"crates/blossom/src/hash.rs\",\n \"byte_length\": 11251,\n \"sha256\": \"753eff6ef9a810045c88839d39a46b37d62a4ad0a5ea57aa30e2a8219e3cdbda\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"food_event_contract\",\n \"path\": \"crates/event/src/food_availability.rs\",\n \"byte_length\": 45680,\n \"sha256\": \"1c8c3fba6514f9b246545b3305e8ac2742258857d1b813fa34c5fbefa6135e12\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"food_admission\",\n \"path\": \"crates/event_codec/src/food_availability/admission.rs\",\n \"byte_length\": 5799,\n \"sha256\": \"727ebf8f086c14376aba745a0a02b269115fed01e8ce95f90fdd211b9640f842\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"registry_v7_admission\",\n \"path\": \"crates/event_codec/src/admission/registry_v7.rs\",\n \"byte_length\": 5350,\n \"sha256\": \"755e63dd7ad1115c219e5a3ea540bef67d2770fc9f2a5aa6ba97c925c99bdced\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"registry_v7_food_projection\",\n \"path\": \"crates/event_codec/src/food_availability/inbound/registry_v7.rs\",\n \"byte_length\": 26865,\n \"sha256\": \"908015346eaec97bee6f44fe2a524410b701529ac19a5dab4505706d40d527da\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_store_error_surface\",\n \"path\": \"crates/event_store/src/error.rs\",\n \"byte_length\": 17557,\n \"sha256\": \"ac206fafdc67e4c25f4a2f1bcd38eb34ae224b38aca55894b1a9cc67242d8b1a\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"generated_descriptor_registration\",\n \"path\": \"crates/event_store/src/generated.rs\",\n \"byte_length\": 100,\n \"sha256\": \"ddd71b2245f307cac0c8ef835311d0dd9eb2fdaf9d2a76a6c9dc98e56f4faaec\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"public_surface\",\n \"path\": \"crates/event_store/src/lib.rs\",\n \"byte_length\": 3419,\n \"sha256\": \"d5bc071309fd4ec9e26a3cfe9c0e7c00b5de5b6c248902b888891b39e6780d23\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"migration_registry\",\n \"path\": \"crates/event_store/src/migrations.rs\",\n \"byte_length\": 55541,\n \"sha256\": \"ef62808fe75b5c0704567eecccfe23d0b11ae25d332bc5e38451ea2a446c535a\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"model_registration\",\n \"path\": \"crates/event_store/src/model.rs\",\n \"byte_length\": 33617,\n \"sha256\": \"79296b8f263aa06d17005795e4515f769f064ea6fd971eeb1296e1151debaf20\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"schema_hooks\",\n \"path\": \"crates/event_store/src/schema.rs\",\n \"byte_length\": 97574,\n \"sha256\": \"6d259548559f32e259d3502787ccd4efbd22eebd1406dd7dd68c8f3145411543\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"store_ingest_and_wal_authority\",\n \"path\": \"crates/event_store/src/store.rs\",\n \"byte_length\": 357693,\n \"sha256\": \"8bca94e5c7b26cee60a06ea327fcba385e6cbc51550f1774ef4d0488ffa2727b\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"addressable_transition_feed_model\",\n \"path\": \"crates/event_store/src/model/addressable_transition_feed_v1.rs\",\n \"byte_length\": 22314,\n \"sha256\": \"b1c6b0a68f34459f7e14bd63857596154c0aa3fd02dc6c1661d543bb681324a7\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"current_visibility_model\",\n \"path\": \"crates/event_store/src/model/current_visibility_v1.rs\",\n \"byte_length\": 5691,\n \"sha256\": \"25ec92f45006e2f66f2e1c8b954a021334bb1595b849c4d8529f289d3f7aeb25\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"food_projection_model\",\n \"path\": \"crates/event_store/src/model/food_availability_projection_v1.rs\",\n \"byte_length\": 17493,\n \"sha256\": \"1e5ff9c05a81fda223ed1a27ff18a1b08bcdeaec9047a13fdd577390b3e0fdb9\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"addressable_transition_feed_store\",\n \"path\": \"crates/event_store/src/store/addressable_transition_feed_v1.rs\",\n \"byte_length\": 40253,\n \"sha256\": \"fe23424aa1e6b39f9aba2dfa4470652b26b4990f91204a2bdfe379c03da9b610\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"current_visibility_store\",\n \"path\": \"crates/event_store/src/store/current_visibility_v1.rs\",\n \"byte_length\": 15860,\n \"sha256\": \"8615086e674c30700305debcef11de5b3dbfe5aec735c0f58b4ac11caa518596\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"food_projection_store\",\n \"path\": \"crates/event_store/src/store/food_availability_projection_v1.rs\",\n \"byte_length\": 49029,\n \"sha256\": \"0cec060c50c50d9333e0583e338fe311a1c64a1d586c222e391d8cef685cf871\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"predecessor_protocol_storage\",\n \"path\": \"crates/event_store/src/store/protocol_storage_v1.rs\",\n \"byte_length\": 10975,\n \"sha256\": \"155c74d27eee5db1d6f0f844f9d319604eefbbf640f4b2371ac5d0e370816e50\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"predecessor_active_state_fast_validation\",\n \"path\": \"crates/event_store/src/nip09/reconciliation_v1.rs\",\n \"byte_length\": 183733,\n \"sha256\": \"3bddb664491bd9abe878f5b2441d1230fb188368dae341f3425a2b035211366a\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"post_core_capabilities\",\n \"path\": \"crates/event_store/src/store/post_core_extension_capabilities.rs\",\n \"byte_length\": 1255,\n \"sha256\": \"cb434372156cb7ff31dac392d7095c2e5f44b128fae4e705516d6d000e2e2502\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"post_core_dispatcher\",\n \"path\": \"crates/event_store/src/store/post_core_extension_dispatcher.rs\",\n \"byte_length\": 576,\n \"sha256\": \"df62ee92e9f165502d5e533997a47f533129fd3cffab2d9b2012e2ed22405f48\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"post_core_v2_extension\",\n \"path\": \"crates/event_store/src/store/post_core_extensions_v2.rs\",\n \"byte_length\": 294,\n \"sha256\": \"8dcbc503ed9ea6fb06ed9a2a83b0804d928f9590b5706de25a057ad72c0d38d2\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"post_core_v2_storage\",\n \"path\": \"crates/event_store/src/store/post_core_storage_v2.rs\",\n \"byte_length\": 632,\n \"sha256\": \"4b672770f3c34bf887e4cc949c068cb0c87396cb4af8efb6e13d39aa4e0d973a\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"predecessor_post_core_v1_extension\",\n \"path\": \"crates/event_store/src/store/post_core_extensions_v1.rs\",\n \"byte_length\": 6935,\n \"sha256\": \"fb165704c64d982cf3be0a880c44985be6b375758451e94b2aaaf30881769f18\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"predecessor_post_core_v1_storage\",\n \"path\": \"crates/event_store/src/store/post_core_storage_v1.rs\",\n \"byte_length\": 16871,\n \"sha256\": \"a6dca0884762cec3c32e460d17662ced9d0335f30e79b3d5fdb3461259d3ec19\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n }\n ],\n \"public_api\": [\n \"RADROOTS_ADDRESSABLE_TRANSITION_CURSOR_JSON_MAX_BYTES_V1\",\n \"RADROOTS_ADDRESSABLE_TRANSITION_D_TAG_MAX_BYTES_V1\",\n \"RADROOTS_ADDRESSABLE_TRANSITION_FEED_VERSION_V1\",\n \"RADROOTS_ADDRESSABLE_TRANSITION_PAGE_LIMIT_MAX_V1\",\n \"RADROOTS_ADDRESSABLE_TRANSITION_PAGE_RAW_JSON_MAX_BYTES_V1\",\n \"RADROOTS_ADDRESSABLE_TRANSITION_PAGE_SCAN_MAX_V1\",\n \"RADROOTS_ADDRESSABLE_TRANSITION_SCOPE_KIND_MAX_V1\",\n \"RADROOTS_FOOD_AVAILABILITY_PROJECTION_APPLY_PAGE_LIMIT_V1\",\n \"RADROOTS_FOOD_AVAILABILITY_PROJECTION_VERSION_V1\",\n \"RADROOTS_FOOD_AVAILABILITY_SEARCH_QUERY_MAX_BYTES_V1\",\n \"RADROOTS_FOOD_AVAILABILITY_SEARCH_QUERY_MAX_TERMS_V1\",\n \"RadrootsAddressableTransitionCauseV1\",\n \"RadrootsAddressableTransitionCoordinateV1\",\n \"RadrootsAddressableTransitionCursorV1\",\n \"RadrootsAddressableTransitionEventReferenceV1\",\n \"RadrootsAddressableTransitionOriginV1\",\n \"RadrootsAddressableTransitionPageV1\",\n \"RadrootsAddressableTransitionRawHeadDecisionV1\",\n \"RadrootsAddressableTransitionScopeFingerprintV1\",\n \"RadrootsAddressableTransitionScopeV1\",\n \"RadrootsAddressableTransitionV1\",\n \"RadrootsAddressableTransitionVisibilityV1\",\n \"RadrootsCurrentEventVisibilityV1\",\n \"RadrootsCurrentVisibilityDecisionV1\",\n \"RadrootsFoodAvailabilitySearchQueryV1\",\n \"RadrootsFoodAvailabilityStatusFilterV1\",\n \"RadrootsNip09SuppressionEvidenceV1\",\n \"RadrootsNip09SuppressionOutcome\",\n \"RadrootsNip09SuppressionReason\",\n \"RadrootsStoreProducedCanonicalEventV1\",\n \"RadrootsStoredFoodAvailabilityImageV1\",\n \"RadrootsStoredFoodAvailabilityV1\"\n ],\n \"result_vector\": {\n \"canonical_path\": \"contracts/conformance/vectors/event_store/food_availability_projection.v1.json\",\n \"mirror_path\": \"crates/event_store/tests/fixtures/food_availability_projection.v1.json\",\n \"byte_length\": 103659,\n \"sha256\": \"fca2b71b47736ed04ed1e908823b65b3fc3cf0366cb162128369fe328295bb63\",\n \"hash_algorithm\": \"sha256_bytes_v1\",\n \"executor_id\": \"radroots_event_store.food_availability_projection_v1.result_vector_executor.v1\",\n \"executor_path\": \"crates/event_store/tests/food_availability_projection_v1_result_vector.rs\",\n \"executor_test\": \"food_availability_projection_v1_result_vector\",\n \"executor_byte_length\": 34078,\n \"executor_sha256\": \"59e20d81562299cf9dd942dd637b5ca404c7aacc98c7ce3fbf1e14751c1b2d9b\",\n \"executor_hash_algorithm\": \"sha256_bytes_v1\"\n }\n}\n"; pub(crate) const FOOD_AVAILABILITY_PROJECTION_MANIFEST_BYTE_LENGTH: usize = 17455; pub(crate) const FOOD_AVAILABILITY_PROJECTION_MANIFEST_SHA256: &str = - "33b93a3c87ce428e8aa6f5e92643c77203d9aa006c53ce96f3562fe6d68ffd23"; + "02dfe1b450fbdac16e718888215b4dd5c85d8975440fa21e8f439fb24c2b2990"; pub(crate) const FOOD_AVAILABILITY_PROJECTION_MANIFEST_SCHEMA_VERSION: u32 = 1; pub(crate) const FOOD_AVAILABILITY_PROJECTION_CONTRACT_ID: &str = "radroots_event_store.food_availability_projection_v1"; @@ -32,4 +32,4 @@ pub(crate) const FOOD_AVAILABILITY_PROJECTION_RESULT_VECTOR_SHA256: &str = pub(crate) const FOOD_AVAILABILITY_PROJECTION_RESULT_VECTOR_EXECUTOR_ID: &str = "radroots_event_store.food_availability_projection_v1.result_vector_executor.v1"; pub(crate) const FOOD_AVAILABILITY_PROJECTION_RESULT_VECTOR_EXECUTOR_SHA256: &str = - "9e8e11abae7bbc7dda30eab6f0a79074ffc3761aa6b955cff58c4c62fa581aa3"; + "59e20d81562299cf9dd942dd637b5ca404c7aacc98c7ce3fbf1e14751c1b2d9b"; diff --git a/crates/event_store/src/generated/source_maintenance_manifest.rs b/crates/event_store/src/generated/source_maintenance_manifest.rs @@ -1,8 +1,8 @@ // @generated by `cargo xtask contract source-maintenance-manifest --write`; do not edit. -pub(crate) const SOURCE_MAINTENANCE_MANIFEST_JSON: &str = "{\n \"schema_version\": 1,\n \"contract_id\": \"radroots_event_store.source_maintenance_v1\",\n \"hook_id\": \"source_maintenance_v1\",\n \"manifest_schema\": {\n \"path\": \"crates/event_store/contracts/source_maintenance_v1.manifest.schema.json\",\n \"byte_length\": 12315,\n \"sha256\": \"ad4a6c8ae9488fc8033792bc6952af04687f312901c1847d8c668a62913bb642\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n \"predecessor\": {\n \"hook_id\": \"food_availability_projection_v1\",\n \"manifest\": {\n \"path\": \"crates/event_store/contracts/food_availability_projection_v1.manifest.json\",\n \"byte_length\": 17455,\n \"sha256\": \"33b93a3c87ce428e8aa6f5e92643c77203d9aa006c53ce96f3562fe6d68ffd23\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n }\n },\n \"migration\": {\n \"version\": 4,\n \"name\": \"source_maintenance\",\n \"up\": {\n \"path\": \"crates/event_store/migrations/0004_source_maintenance.up.sql\",\n \"byte_length\": 19841,\n \"sha256\": \"425dc799f392b87f265a6fb81f89c4a1c7a5db8391ab0380970708cb9c66704d\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n \"down\": {\n \"path\": \"crates/event_store/migrations/0004_source_maintenance.down.sql\",\n \"byte_length\": 5172,\n \"sha256\": \"fe44fd53c51545c08ea479b385e6781079dab70fc63da2a3c205d727a00ce860\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n \"schema_sha256\": \"d526d96ea02be12b4b0aed99e97cfdde17c4474ace67111506a7b900ee78b186\",\n \"catalog\": {\n \"objects\": [\n \"radroots_event_store_source_capacity_delete_guard\",\n \"radroots_event_store_source_capacity_insert_guard\",\n \"radroots_event_store_source_capacity_marker_close_guard\",\n \"radroots_event_store_source_capacity_update_guard\",\n \"radroots_event_store_source_capacity_v1\",\n \"radroots_event_store_source_generation_capacity_advance\",\n \"radroots_event_store_source_generation_capacity_guard\"\n ],\n \"replaced_objects\": [\n \"radroots_event_store_food_availability_image_delete_guard\",\n \"radroots_event_store_food_availability_projection_delete_guard\",\n \"radroots_event_store_source_rebuild_marker_insert_guard\"\n ],\n \"tables\": [\n \"radroots_event_store_source_capacity_v1\"\n ],\n \"fts5_tables\": []\n }\n },\n \"source_maintenance\": {\n \"version\": 1,\n \"event_contract_registry_version\": 7,\n \"capacity_authority_id\": \"radroots_event_store_source_capacity_v1\",\n \"accounting\": {\n \"algorithm\": \"sqlite_cast_blob_octet_sum_v1\",\n \"raw_event_columns\": [\n \"event_id\",\n \"pubkey\",\n \"tags_json\",\n \"content\",\n \"sig\",\n \"raw_json\"\n ],\n \"raw_tag_columns\": [\n \"event_id\",\n \"tag_name\",\n \"tag_value\",\n \"tag_json\"\n ],\n \"nullable_raw_tag_columns\": [\n \"tag_value\"\n ]\n },\n \"limits\": {\n \"raw_events\": 25000,\n \"raw_tags\": 250000,\n \"raw_event_text_bytes\": 67108864,\n \"raw_tag_text_bytes\": 33554432,\n \"retained_source_generations\": 8\n },\n \"reopen_validation\": {\n \"mode\": \"bounded_full_raw_recount_v1\",\n \"raw_event_rejection_scan_bound\": 25001,\n \"raw_tag_rejection_scan_bound\": 250001,\n \"generation_history_validation\": \"bounded_count_plus_active_ordinal_v1\",\n \"retained_generation_rejection_scan_bound\": 9\n },\n \"rebuild_seal\": {\n \"nip09_hook_id\": \"nip09_reconciliation_v1\",\n \"nip09_manifest_sha256\": \"74af832420ffbaa9805e89df3c0b34f126a443e1598f757e3372f407f9003b77\",\n \"food_hook_id\": \"food_availability_projection_v1\",\n \"food_manifest_sha256\": \"33b93a3c87ce428e8aa6f5e92643c77203d9aa006c53ce96f3562fe6d68ffd23\",\n \"food_scope_fingerprint_sha256\": \"8b63c5ddc48a2cc7db69295238b96d5f814dba50427c80b4d0079f061e6d3de0\",\n \"active_generation_authority\": \"radroots_event_store_source_state\",\n \"marker_close_authority\": \"radroots_event_store_source_capacity_marker_close_guard\"\n }\n },\n \"entry_points\": [\n {\n \"role\": \"migration_registry\",\n \"rust_path\": \"radroots_event_store::migrations::EVENT_STORE_MIGRATIONS[3]\"\n },\n {\n \"role\": \"migration_apply_hook\",\n \"rust_path\": \"radroots_event_store::schema::apply_migration_hook\"\n },\n {\n \"role\": \"migration_validation_hook\",\n \"rust_path\": \"radroots_event_store::schema::validate_migration_hook_state\"\n },\n {\n \"role\": \"capacity_query\",\n \"rust_path\": \"radroots_event_store::RadrootsEventStore::source_capacity_v1\"\n },\n {\n \"role\": \"raw_append_preflight\",\n \"rust_path\": \"radroots_event_store::source_maintenance_v1::preflight_unique_raw_source_append_v1\"\n },\n {\n \"role\": \"raw_append_advance\",\n \"rust_path\": \"radroots_event_store::source_maintenance_v1::advance_source_capacity_after_insert_v1\"\n },\n {\n \"role\": \"generation_append_preflight\",\n \"rust_path\": \"radroots_event_store::source_maintenance_v1::preflight_source_generation_append_v1\"\n },\n {\n \"role\": \"generation_rebuild_bind\",\n \"rust_path\": \"radroots_event_store::source_maintenance_v1::bind_source_capacity_to_generation_v1\"\n },\n {\n \"role\": \"sqlite_encoding_preflight\",\n \"rust_path\": \"radroots_event_store::store::validate_main_database_encoding\"\n },\n {\n \"role\": \"source_generation_history_rollback_guard\",\n \"rust_path\": \"radroots_event_store::schema::validate_rollback_preserves_source_generation_history\"\n },\n {\n \"role\": \"result_vector_executor\",\n \"rust_path\": \"source_maintenance_v1_result_vector\"\n }\n ],\n \"source_files\": [\n {\n \"role\": \"workspace_dependency_authority\",\n \"path\": \"Cargo.toml\",\n \"byte_length\": 12385,\n \"sha256\": \"c53c5c5a464267d7df850e03fdfa99dcde0b469972cf921f9b81c18b52a9c4b2\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"core_currency_value_authority\",\n \"path\": \"crates/core/src/currency.rs\",\n \"byte_length\": 4142,\n \"sha256\": \"42e6da2d8d2fdd6955dc2d83e98dd00266e02bc910b69923b117662c05089d14\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"core_decimal_value_authority\",\n \"path\": \"crates/core/src/decimal.rs\",\n \"byte_length\": 7839,\n \"sha256\": \"4b1d681a92d7a9e074bee7e1f20eb1499bb05bfc6528a6c9ba69fa7d00416550\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"core_money_value_authority\",\n \"path\": \"crates/core/src/money.rs\",\n \"byte_length\": 8025,\n \"sha256\": \"3f30bc21e21951a62fdc5d4033736ed42a883df590e8403940775bd2edfeebc5\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"core_percent_value_authority\",\n \"path\": \"crates/core/src/percent.rs\",\n \"byte_length\": 2652,\n \"sha256\": \"42ceab109881329f3539d06a0ee0381ab4359985fe185a18d58a9c9558c5eb7f\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"core_quantity_value_authority\",\n \"path\": \"crates/core/src/quantity.rs\",\n \"byte_length\": 6785,\n \"sha256\": \"d14e619da3829cdaf3ca7385fb892d330c286c1e21455c135c37518cbb588b5f\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"core_quantity_price_value_authority\",\n \"path\": \"crates/core/src/quantity_price.rs\",\n \"byte_length\": 7061,\n \"sha256\": \"d60f70377099470ed283f45868a5119d7bb46143cb250b5082a4c038ba7f6cdc\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"core_unit_value_authority\",\n \"path\": \"crates/core/src/unit.rs\",\n \"byte_length\": 10023,\n \"sha256\": \"550e9582b6a5290aac3f637b83853b21fefcbab92c432d067c83448f4b2fe3e9\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_store_error_and_limits\",\n \"path\": \"crates/event_store/src/error.rs\",\n \"byte_length\": 19421,\n \"sha256\": \"4772e041cb20a4963afb2f3159804c777e2f2be61bfdb6ee267e7a7c04258972\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"generated_descriptor_registration\",\n \"path\": \"crates/event_store/src/generated.rs\",\n \"byte_length\": 144,\n \"sha256\": \"6b0a8d6f249bd4fc3f878d37cb5e418680f0f1be2d9eec2518dedf03efc47121\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"public_surface\",\n \"path\": \"crates/event_store/src/lib.rs\",\n \"byte_length\": 3844,\n \"sha256\": \"3cd9653bcb752fb3c4442d4904b98a0a6208011a9a238125b7b7073d7f4e312b\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"migration_registry\",\n \"path\": \"crates/event_store/src/migrations.rs\",\n \"byte_length\": 73585,\n \"sha256\": \"a47477d04759ec6e71d14d3d05459864eae78fce0e3c2481a1b03147f04637f7\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"predecessor_model_public_surface\",\n \"path\": \"crates/event_store/src/model.rs\",\n \"byte_length\": 33617,\n \"sha256\": \"79296b8f263aa06d17005795e4515f769f064ea6fd971eeb1296e1151debaf20\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"source_generation_rebuild_authority\",\n \"path\": \"crates/event_store/src/nip09/reconciliation_v1.rs\",\n \"byte_length\": 184407,\n \"sha256\": \"c455d40fc736e3db264f567c7809af7bd897d89be8a33dfb21667a6ef6b8d6c6\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"schema_migration_and_reopen_authority\",\n \"path\": \"crates/event_store/src/schema.rs\",\n \"byte_length\": 146146,\n \"sha256\": \"93b060e80d3edd73f86208e4bf698fa9d53eaf1eeb04526c9261fb8b5726fb0d\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"public_store_and_transaction_authority\",\n \"path\": \"crates/event_store/src/store.rs\",\n \"byte_length\": 394574,\n \"sha256\": \"db57dc3e35e64c7194683142fe55edba853671a829269449dd2273056dfc3a0e\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"raw_ingest_capacity_authority\",\n \"path\": \"crates/event_store/src/store/protocol_reconciliation_v1.rs\",\n \"byte_length\": 30140,\n \"sha256\": \"210112eeaa6975a3b4fbb97d5c52588f8c6d8d07975e531d39737fd11235de51\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"source_maintenance_runtime\",\n \"path\": \"crates/event_store/src/source_maintenance_v1.rs\",\n \"byte_length\": 51756,\n \"sha256\": \"f8d5b62f0613104aa86658d5bf1baade92c7df83f00ef0cddadd734b9797afca\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"artifact_transaction_authority\",\n \"path\": \"tools/xtask/src/contract/artifact_bundle.rs\",\n \"byte_length\": 38279,\n \"sha256\": \"f326ea57b56d40135f95b6b1e15961f66eed363337180a6d12a5ea903e1a9a29\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"predecessor_successor_governance\",\n \"path\": \"tools/xtask/src/contract/food_availability_projection.rs\",\n \"byte_length\": 194594,\n \"sha256\": \"b859df0608b000f0de53f6543d2dea9501fa9080f57e3fdd8d9e71acf386e0a7\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"transitive_predecessor_membership_governance\",\n \"path\": \"tools/xtask/src/contract/nip09_reconciliation.rs\",\n \"byte_length\": 835558,\n \"sha256\": \"6218e33cc8445fce59194508f73290e7eea8c91495fbe77a5323b258ef21f4a6\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"source_maintenance_governance\",\n \"path\": \"tools/xtask/src/contract/source_maintenance.rs\",\n \"byte_length\": 177996,\n \"sha256\": \"c309da38f12101d77c4de1caa49ef443252cac6238b49692182851c2cf894bda\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"contract_command_authority\",\n \"path\": \"tools/xtask/src/contract.rs\",\n \"byte_length\": 500241,\n \"sha256\": \"972e2a6b1099267e11d9a34e73fd38b20fc217a3dd79bd9a0f1f060b680ba2ba\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"xtask_dispatch_and_release_preflight\",\n \"path\": \"tools/xtask/src/main.rs\",\n \"byte_length\": 14976,\n \"sha256\": \"42b59a8576e4f86b091941a64349ac9eaa20b1e3b52aef367bb3d5947d8ccd1d\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n }\n ],\n \"public_api\": {\n \"inherited_predecessor_symbols\": [\n \"RADROOTS_ADDRESSABLE_TRANSITION_CURSOR_JSON_MAX_BYTES_V1\",\n \"RADROOTS_ADDRESSABLE_TRANSITION_D_TAG_MAX_BYTES_V1\",\n \"RADROOTS_ADDRESSABLE_TRANSITION_FEED_VERSION_V1\",\n \"RADROOTS_ADDRESSABLE_TRANSITION_PAGE_LIMIT_MAX_V1\",\n \"RADROOTS_ADDRESSABLE_TRANSITION_PAGE_RAW_JSON_MAX_BYTES_V1\",\n \"RADROOTS_ADDRESSABLE_TRANSITION_PAGE_SCAN_MAX_V1\",\n \"RADROOTS_ADDRESSABLE_TRANSITION_SCOPE_KIND_MAX_V1\",\n \"RADROOTS_FOOD_AVAILABILITY_PROJECTION_APPLY_PAGE_LIMIT_V1\",\n \"RADROOTS_FOOD_AVAILABILITY_PROJECTION_VERSION_V1\",\n \"RADROOTS_FOOD_AVAILABILITY_SEARCH_QUERY_MAX_BYTES_V1\",\n \"RADROOTS_FOOD_AVAILABILITY_SEARCH_QUERY_MAX_TERMS_V1\",\n \"RadrootsAddressableTransitionCauseV1\",\n \"RadrootsAddressableTransitionCoordinateV1\",\n \"RadrootsAddressableTransitionCursorV1\",\n \"RadrootsAddressableTransitionEventReferenceV1\",\n \"RadrootsAddressableTransitionOriginV1\",\n \"RadrootsAddressableTransitionPageV1\",\n \"RadrootsAddressableTransitionRawHeadDecisionV1\",\n \"RadrootsAddressableTransitionScopeFingerprintV1\",\n \"RadrootsAddressableTransitionScopeV1\",\n \"RadrootsAddressableTransitionV1\",\n \"RadrootsAddressableTransitionVisibilityV1\",\n \"RadrootsCurrentEventVisibilityV1\",\n \"RadrootsCurrentVisibilityDecisionV1\",\n \"RadrootsFoodAvailabilitySearchQueryV1\",\n \"RadrootsFoodAvailabilityStatusFilterV1\",\n \"RadrootsNip09SuppressionEvidenceV1\",\n \"RadrootsNip09SuppressionOutcome\",\n \"RadrootsNip09SuppressionReason\",\n \"RadrootsStoreProducedCanonicalEventV1\",\n \"RadrootsStoredFoodAvailabilityImageV1\",\n \"RadrootsStoredFoodAvailabilityV1\"\n ],\n \"added_symbols\": [\n \"RADROOTS_EVENT_STORE_RAW_EVENT_COUNT_LIMIT_V1\",\n \"RADROOTS_EVENT_STORE_RAW_EVENT_TEXT_BYTES_LIMIT_V1\",\n \"RADROOTS_EVENT_STORE_RAW_TAG_COUNT_LIMIT_V1\",\n \"RADROOTS_EVENT_STORE_RAW_TAG_TEXT_BYTES_LIMIT_V1\",\n \"RADROOTS_EVENT_STORE_RETAINED_SOURCE_GENERATION_LIMIT_V1\",\n \"RadrootsEventStoreSourceCapacityResourceV1\",\n \"RadrootsEventStoreSourceCapacityV1\"\n ],\n \"methods\": [\n \"RadrootsEventStore::source_capacity_v1\",\n \"RadrootsEventStoreSourceCapacityResourceV1::as_str\",\n \"RadrootsEventStoreSourceCapacityV1::source_generation\",\n \"RadrootsEventStoreSourceCapacityV1::raw_event_count\",\n \"RadrootsEventStoreSourceCapacityV1::raw_tag_count\",\n \"RadrootsEventStoreSourceCapacityV1::raw_event_text_bytes\",\n \"RadrootsEventStoreSourceCapacityV1::raw_tag_text_bytes\",\n \"RadrootsEventStoreSourceCapacityV1::raw_high_water_seq\",\n \"RadrootsEventStoreSourceCapacityV1::retained_generation_count\",\n \"RadrootsEventStoreSourceCapacityV1::retained_generation_limit\"\n ],\n \"error_variants\": [\n \"SourceCapacityExceeded\",\n \"SourceGenerationHistoryLimitReached\",\n \"PersistedEphemeralRawEvent\",\n \"SourceCapacityStateDrift\",\n \"SqliteMainDatabaseEncodingNotUtf8\",\n \"RollbackWouldDiscardSourceGenerationHistory\"\n ],\n \"removed_symbols\": [\n \"RadrootsEventStoreReconciliationResource\",\n \"RadrootsEventStoreError::ReconciliationCapacityExceeded\"\n ],\n \"breaking_replacements\": [\n {\n \"removed\": \"RadrootsEventStoreReconciliationResource\",\n \"replacement\": \"RadrootsEventStoreSourceCapacityResourceV1\"\n },\n {\n \"removed\": \"RadrootsEventStoreError::ReconciliationCapacityExceeded\",\n \"replacement\": \"RadrootsEventStoreError::SourceCapacityExceeded\"\n }\n ]\n },\n \"result_vector\": {\n \"canonical_path\": \"contracts/conformance/vectors/event_store/source_maintenance.v1.json\",\n \"mirror_path\": \"crates/event_store/tests/fixtures/source_maintenance.v1.json\",\n \"byte_length\": 16253,\n \"sha256\": \"997aba2604a2b9d199fb87dc9d07942ca50d91863aeadcf3eeacf16d191dd71f\",\n \"hash_algorithm\": \"sha256_bytes_v1\",\n \"executor_id\": \"radroots_event_store.source_maintenance_v1.result_vector_executor.v1\",\n \"executor_path\": \"crates/event_store/tests/source_maintenance_v1_result_vector.rs\",\n \"executor_test\": \"source_maintenance_v1_result_vector\",\n \"executor_byte_length\": 23510,\n \"executor_sha256\": \"a7487afdfe19fc5fc794811d0f0e6035203e1aabcf0a33a1d398f6b3555d38f3\",\n \"executor_hash_algorithm\": \"sha256_bytes_v1\"\n }\n}\n"; -pub(crate) const SOURCE_MAINTENANCE_MANIFEST_BYTE_LENGTH: usize = 16260; +pub(crate) const SOURCE_MAINTENANCE_MANIFEST_JSON: &str = "{\n \"schema_version\": 1,\n \"contract_id\": \"radroots_event_store.source_maintenance_v1\",\n \"hook_id\": \"source_maintenance_v1\",\n \"manifest_schema\": {\n \"path\": \"crates/event_store/contracts/source_maintenance_v1.manifest.schema.json\",\n \"byte_length\": 12315,\n \"sha256\": \"96ea98a5abf3348b61565954cd34f2c622411d8dd34205ef04134bbe0e3d3f2b\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n \"predecessor\": {\n \"hook_id\": \"food_availability_projection_v1\",\n \"manifest\": {\n \"path\": \"crates/event_store/contracts/food_availability_projection_v1.manifest.json\",\n \"byte_length\": 17455,\n \"sha256\": \"02dfe1b450fbdac16e718888215b4dd5c85d8975440fa21e8f439fb24c2b2990\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n }\n },\n \"migration\": {\n \"version\": 4,\n \"name\": \"source_maintenance\",\n \"up\": {\n \"path\": \"crates/event_store/migrations/0004_source_maintenance.up.sql\",\n \"byte_length\": 19841,\n \"sha256\": \"ab2724188f8d08c897eebea2533a635e7c74282a25e84e4c0c37e78b08837a43\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n \"down\": {\n \"path\": \"crates/event_store/migrations/0004_source_maintenance.down.sql\",\n \"byte_length\": 5172,\n \"sha256\": \"fe44fd53c51545c08ea479b385e6781079dab70fc63da2a3c205d727a00ce860\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n \"schema_sha256\": \"074f85b663444ac150239ecd8441ea4a96ad83a798a55e22d2e5e2f7ee943a8c\",\n \"catalog\": {\n \"objects\": [\n \"radroots_event_store_source_capacity_delete_guard\",\n \"radroots_event_store_source_capacity_insert_guard\",\n \"radroots_event_store_source_capacity_marker_close_guard\",\n \"radroots_event_store_source_capacity_update_guard\",\n \"radroots_event_store_source_capacity_v1\",\n \"radroots_event_store_source_generation_capacity_advance\",\n \"radroots_event_store_source_generation_capacity_guard\"\n ],\n \"replaced_objects\": [\n \"radroots_event_store_food_availability_image_delete_guard\",\n \"radroots_event_store_food_availability_projection_delete_guard\",\n \"radroots_event_store_source_rebuild_marker_insert_guard\"\n ],\n \"tables\": [\n \"radroots_event_store_source_capacity_v1\"\n ],\n \"fts5_tables\": []\n }\n },\n \"source_maintenance\": {\n \"version\": 1,\n \"event_contract_registry_version\": 7,\n \"capacity_authority_id\": \"radroots_event_store_source_capacity_v1\",\n \"accounting\": {\n \"algorithm\": \"sqlite_cast_blob_octet_sum_v1\",\n \"raw_event_columns\": [\n \"event_id\",\n \"pubkey\",\n \"tags_json\",\n \"content\",\n \"sig\",\n \"raw_json\"\n ],\n \"raw_tag_columns\": [\n \"event_id\",\n \"tag_name\",\n \"tag_value\",\n \"tag_json\"\n ],\n \"nullable_raw_tag_columns\": [\n \"tag_value\"\n ]\n },\n \"limits\": {\n \"raw_events\": 25000,\n \"raw_tags\": 250000,\n \"raw_event_text_bytes\": 67108864,\n \"raw_tag_text_bytes\": 33554432,\n \"retained_source_generations\": 8\n },\n \"reopen_validation\": {\n \"mode\": \"bounded_full_raw_recount_v1\",\n \"raw_event_rejection_scan_bound\": 25001,\n \"raw_tag_rejection_scan_bound\": 250001,\n \"generation_history_validation\": \"bounded_count_plus_active_ordinal_v1\",\n \"retained_generation_rejection_scan_bound\": 9\n },\n \"rebuild_seal\": {\n \"nip09_hook_id\": \"nip09_reconciliation_v1\",\n \"nip09_manifest_sha256\": \"74af832420ffbaa9805e89df3c0b34f126a443e1598f757e3372f407f9003b77\",\n \"food_hook_id\": \"food_availability_projection_v1\",\n \"food_manifest_sha256\": \"02dfe1b450fbdac16e718888215b4dd5c85d8975440fa21e8f439fb24c2b2990\",\n \"food_scope_fingerprint_sha256\": \"8b63c5ddc48a2cc7db69295238b96d5f814dba50427c80b4d0079f061e6d3de0\",\n \"active_generation_authority\": \"radroots_event_store_source_state\",\n \"marker_close_authority\": \"radroots_event_store_source_capacity_marker_close_guard\"\n }\n },\n \"entry_points\": [\n {\n \"role\": \"migration_registry\",\n \"rust_path\": \"radroots_event_store::migrations::EVENT_STORE_MIGRATIONS[3]\"\n },\n {\n \"role\": \"migration_apply_hook\",\n \"rust_path\": \"radroots_event_store::schema::apply_migration_hook\"\n },\n {\n \"role\": \"migration_validation_hook\",\n \"rust_path\": \"radroots_event_store::schema::validate_migration_hook_state\"\n },\n {\n \"role\": \"capacity_query\",\n \"rust_path\": \"radroots_event_store::RadrootsEventStore::source_capacity_v1\"\n },\n {\n \"role\": \"raw_append_preflight\",\n \"rust_path\": \"radroots_event_store::source_maintenance_v1::preflight_unique_raw_source_append_v1\"\n },\n {\n \"role\": \"raw_append_advance\",\n \"rust_path\": \"radroots_event_store::source_maintenance_v1::advance_source_capacity_after_insert_v1\"\n },\n {\n \"role\": \"generation_append_preflight\",\n \"rust_path\": \"radroots_event_store::source_maintenance_v1::preflight_source_generation_append_v1\"\n },\n {\n \"role\": \"generation_rebuild_bind\",\n \"rust_path\": \"radroots_event_store::source_maintenance_v1::bind_source_capacity_to_generation_v1\"\n },\n {\n \"role\": \"sqlite_encoding_preflight\",\n \"rust_path\": \"radroots_event_store::store::validate_main_database_encoding\"\n },\n {\n \"role\": \"source_generation_history_rollback_guard\",\n \"rust_path\": \"radroots_event_store::schema::validate_rollback_preserves_source_generation_history\"\n },\n {\n \"role\": \"result_vector_executor\",\n \"rust_path\": \"source_maintenance_v1_result_vector\"\n }\n ],\n \"source_files\": [\n {\n \"role\": \"workspace_dependency_authority\",\n \"path\": \"Cargo.toml\",\n \"byte_length\": 12385,\n \"sha256\": \"c53c5c5a464267d7df850e03fdfa99dcde0b469972cf921f9b81c18b52a9c4b2\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"core_currency_value_authority\",\n \"path\": \"crates/core/src/currency.rs\",\n \"byte_length\": 4142,\n \"sha256\": \"42e6da2d8d2fdd6955dc2d83e98dd00266e02bc910b69923b117662c05089d14\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"core_decimal_value_authority\",\n \"path\": \"crates/core/src/decimal.rs\",\n \"byte_length\": 7839,\n \"sha256\": \"4b1d681a92d7a9e074bee7e1f20eb1499bb05bfc6528a6c9ba69fa7d00416550\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"core_money_value_authority\",\n \"path\": \"crates/core/src/money.rs\",\n \"byte_length\": 8025,\n \"sha256\": \"3f30bc21e21951a62fdc5d4033736ed42a883df590e8403940775bd2edfeebc5\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"core_percent_value_authority\",\n \"path\": \"crates/core/src/percent.rs\",\n \"byte_length\": 2652,\n \"sha256\": \"42ceab109881329f3539d06a0ee0381ab4359985fe185a18d58a9c9558c5eb7f\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"core_quantity_value_authority\",\n \"path\": \"crates/core/src/quantity.rs\",\n \"byte_length\": 6785,\n \"sha256\": \"d14e619da3829cdaf3ca7385fb892d330c286c1e21455c135c37518cbb588b5f\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"core_quantity_price_value_authority\",\n \"path\": \"crates/core/src/quantity_price.rs\",\n \"byte_length\": 7061,\n \"sha256\": \"d60f70377099470ed283f45868a5119d7bb46143cb250b5082a4c038ba7f6cdc\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"core_unit_value_authority\",\n \"path\": \"crates/core/src/unit.rs\",\n \"byte_length\": 10023,\n \"sha256\": \"550e9582b6a5290aac3f637b83853b21fefcbab92c432d067c83448f4b2fe3e9\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"blossom_hash_authority\",\n \"path\": \"crates/blossom/src/hash.rs\",\n \"byte_length\": 11251,\n \"sha256\": \"753eff6ef9a810045c88839d39a46b37d62a4ad0a5ea57aa30e2a8219e3cdbda\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"blossom_url_authority\",\n \"path\": \"crates/blossom/src/url.rs\",\n \"byte_length\": 15364,\n \"sha256\": \"05325325da6627ba48318851fb4e61a9ad540aad37fc1c27ac9a47f27300891f\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_contract_facade\",\n \"path\": \"crates/event/src/contract.rs\",\n \"byte_length\": 86,\n \"sha256\": \"9994cbca9dcc7450ad133b6b927e7c06bee08ef813652452cc1e56a284c1be10\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_contract_registry_v7_authority\",\n \"path\": \"crates/event/src/contract/registry_v7.rs\",\n \"byte_length\": 155788,\n \"sha256\": \"6305e487a6d51c0b04ad5620f28530d550e81b28152406cd5f224563ecd72f5c\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_envelope_authority\",\n \"path\": \"crates/event/src/envelope.rs\",\n \"byte_length\": 31165,\n \"sha256\": \"97a3bb38d630666bba497b98e856ee457d6899de230dabf6cab786a5bd55a3ce\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_head_facade\",\n \"path\": \"crates/event/src/event_head.rs\",\n \"byte_length\": 68,\n \"sha256\": \"cb52f6006f7ecd862707d6b048f9fc407e0cd5ebcd3091b3c54e195ffa5cba64\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_head_v1_authority\",\n \"path\": \"crates/event/src/event_head/v1.rs\",\n \"byte_length\": 7529,\n \"sha256\": \"0a4b50c4b7a93e9d88cc995cf69d9e87b341cba66d7feb51c357dfa4e5b2de37\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_ids_authority\",\n \"path\": \"crates/event/src/ids.rs\",\n \"byte_length\": 46282,\n \"sha256\": \"f3c34e7dcf09fc225cb9c12f02ae932d5155c859f73f8b8573db8e5ebf298678\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_trade_authority\",\n \"path\": \"crates/event/src/trade.rs\",\n \"byte_length\": 68376,\n \"sha256\": \"1012b44295cb26844206304bc24b355a49c18a023844f6b3905337c63b1417a7\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_kinds_authority\",\n \"path\": \"crates/event/src/kinds.rs\",\n \"byte_length\": 34961,\n \"sha256\": \"8b3ce6193cab1f7e1587d0c1b2880a81b0aa43c77d89671b602772db37edcebf\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_tags_authority\",\n \"path\": \"crates/event/src/tags.rs\",\n \"byte_length\": 4530,\n \"sha256\": \"cb8f12a639fc72d9238e32495d9e67e928e6627fb8c94ec0a58c5d95e7373cd6\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_draft_authority\",\n \"path\": \"crates/event/src/draft.rs\",\n \"byte_length\": 58674,\n \"sha256\": \"fa4e802f1143eba72ba7fc334104ea0d6613c886725ff9f3e61dab2443c243b6\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_calendar_authority\",\n \"path\": \"crates/event/src/calendar.rs\",\n \"byte_length\": 103969,\n \"sha256\": \"94e07896e8cf3486b55becf2a64be72a5129625bd52a86e70e2a4b273fcf20e5\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_classified_listing_authority\",\n \"path\": \"crates/event/src/classified_listing.rs\",\n \"byte_length\": 8226,\n \"sha256\": \"745aa08953a6243ea1afad22aa63e44f6746f2f243ab0d6b617d6ab64fa58749\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_profile_authority\",\n \"path\": \"crates/event/src/profile.rs\",\n \"byte_length\": 19061,\n \"sha256\": \"f2b03be027aea187645e8bc3ae7a7d4004d6e58d4e1b361b35786ccdc36d907a\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_post_authority\",\n \"path\": \"crates/event/src/post.rs\",\n \"byte_length\": 22813,\n \"sha256\": \"d4a573cf2510f3a261f6aac3efd16489591281cdbdb387af5a7d67f516e1e056\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_comment_authority\",\n \"path\": \"crates/event/src/comment.rs\",\n \"byte_length\": 36375,\n \"sha256\": \"f4d1a57780eff0d315bc4e2fbad316dfb7c7ced1bcc9e8e85afe0b5ecdaf3aa8\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_food_availability_authority\",\n \"path\": \"crates/event/src/food_availability.rs\",\n \"byte_length\": 45680,\n \"sha256\": \"1c8c3fba6514f9b246545b3305e8ac2742258857d1b813fa34c5fbefa6135e12\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_deletion_authority\",\n \"path\": \"crates/event/src/deletion.rs\",\n \"byte_length\": 31155,\n \"sha256\": \"c8b7ab79998ae62e03497f5511dd3950a41d73155edda3d8d34c65fc797e9d09\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_relay_hint_authority\",\n \"path\": \"crates/event/src/relay_hint.rs\",\n \"byte_length\": 14317,\n \"sha256\": \"1a14aea5d2f2620970dc1de9e3d311d9042cab4d5805a56461548168112a0801\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_media_authority\",\n \"path\": \"crates/event/src/media.rs\",\n \"byte_length\": 3821,\n \"sha256\": \"ca98ddb134cb522912900544080d910867398d6aff6e8c6b061dc1fb77212ec3\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_social_authority\",\n \"path\": \"crates/event/src/social.rs\",\n \"byte_length\": 5483,\n \"sha256\": \"1b89c6d0954822e7f1e778479ed43694e88929bcd5310ee066f8f4ba6505045a\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_wire_facade\",\n \"path\": \"crates/event/src/wire.rs\",\n \"byte_length\": 68,\n \"sha256\": \"cb52f6006f7ecd862707d6b048f9fc407e0cd5ebcd3091b3c54e195ffa5cba64\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_wire_v1_authority\",\n \"path\": \"crates/event/src/wire/v1.rs\",\n \"byte_length\": 22133,\n \"sha256\": \"cc28c8cbd962b32ed2efe43e84c1e0d1ea3bd89636efff2d5553714072fce1a4\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_codec_verification_facade\",\n \"path\": \"crates/event_codec/src/verification.rs\",\n \"byte_length\": 253,\n \"sha256\": \"b49a32df605035c87f295c0a151140d43d2e588c5e11b05183e5fc92993dae0e\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_codec_verification_v1_authority\",\n \"path\": \"crates/event_codec/src/verification/v1.rs\",\n \"byte_length\": 8751,\n \"sha256\": \"fc4c5d45e475151c56330ba9c4db70de603e4ec48adabd6365f80d5f6a3733f4\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_codec_registry_v7_admission_authority\",\n \"path\": \"crates/event_codec/src/admission/registry_v7.rs\",\n \"byte_length\": 5350,\n \"sha256\": \"755e63dd7ad1115c219e5a3ea540bef67d2770fc9f2a5aa6ba97c925c99bdced\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_codec_profile_inbound_facade\",\n \"path\": \"crates/event_codec/src/profile/inbound.rs\",\n \"byte_length\": 86,\n \"sha256\": \"9994cbca9dcc7450ad133b6b927e7c06bee08ef813652452cc1e56a284c1be10\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_codec_profile_registry_v7_authority\",\n \"path\": \"crates/event_codec/src/profile/inbound/registry_v7.rs\",\n \"byte_length\": 10394,\n \"sha256\": \"c37c225ea8153beb098a39c4a56203aa03382af12646f40cd3f8628663700702\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_codec_post_inbound_facade\",\n \"path\": \"crates/event_codec/src/post/inbound.rs\",\n \"byte_length\": 86,\n \"sha256\": \"9994cbca9dcc7450ad133b6b927e7c06bee08ef813652452cc1e56a284c1be10\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_codec_post_registry_v7_authority\",\n \"path\": \"crates/event_codec/src/post/inbound/registry_v7.rs\",\n \"byte_length\": 16016,\n \"sha256\": \"bc0bb839c28f3588f05544c846c987528ea3934c75305fef70af8e027a97cc58\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_codec_reply_inbound_facade\",\n \"path\": \"crates/event_codec/src/reply/inbound.rs\",\n \"byte_length\": 86,\n \"sha256\": \"9994cbca9dcc7450ad133b6b927e7c06bee08ef813652452cc1e56a284c1be10\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_codec_reply_registry_v7_authority\",\n \"path\": \"crates/event_codec/src/reply/inbound/registry_v7.rs\",\n \"byte_length\": 26820,\n \"sha256\": \"d49a950c25e36fc145ce9f1762ae345c028e6f2834b63795603741bbe365c3c8\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_codec_comment_inbound_facade\",\n \"path\": \"crates/event_codec/src/comment/inbound.rs\",\n \"byte_length\": 86,\n \"sha256\": \"9994cbca9dcc7450ad133b6b927e7c06bee08ef813652452cc1e56a284c1be10\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_codec_comment_registry_v7_authority\",\n \"path\": \"crates/event_codec/src/comment/inbound/registry_v7.rs\",\n \"byte_length\": 53783,\n \"sha256\": \"30d1b0155963b25d64685ddd042f423ef7707b111dc56ead15bd468e0433a432\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_codec_deletion_facade\",\n \"path\": \"crates/event_codec/src/deletion/mod.rs\",\n \"byte_length\": 115,\n \"sha256\": \"17d56f82ddb0a86bc97abbcf3e037fe460ea31fff2548f527be4bf004dac3a95\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_codec_deletion_reconciliation_v1_authority\",\n \"path\": \"crates/event_codec/src/deletion/reconciliation_v1.rs\",\n \"byte_length\": 38469,\n \"sha256\": \"3e06d1fa923ca5faabb1e95338c35650b0e20b078ff5c972e35ab845d8b7476c\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_codec_food_inbound_facade\",\n \"path\": \"crates/event_codec/src/food_availability/inbound.rs\",\n \"byte_length\": 86,\n \"sha256\": \"9994cbca9dcc7450ad133b6b927e7c06bee08ef813652452cc1e56a284c1be10\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_codec_food_registry_v7_authority\",\n \"path\": \"crates/event_codec/src/food_availability/inbound/registry_v7.rs\",\n \"byte_length\": 26865,\n \"sha256\": \"908015346eaec97bee6f44fe2a524410b701529ac19a5dab4505706d40d527da\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_codec_job_traits_authority\",\n \"path\": \"crates/event_codec/src/job/traits.rs\",\n \"byte_length\": 5029,\n \"sha256\": \"353df3703de4d99fc318474952dc6c95cbce9a19756f3e235ed2d715f36c4364\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_store_dependency_authority\",\n \"path\": \"crates/event_store/Cargo.toml\",\n \"byte_length\": 1569,\n \"sha256\": \"30f43004bcf0ffa9b9b6f338cba8c56be0265bc1cee708e93f7b7dc54ed60f9c\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_store_error_and_limits\",\n \"path\": \"crates/event_store/src/error.rs\",\n \"byte_length\": 19517,\n \"sha256\": \"4bf24ee1aa6117597ab467b1379a05549b79024213dc7622a2d276bc26fffab4\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"generated_descriptor_registration\",\n \"path\": \"crates/event_store/src/generated.rs\",\n \"byte_length\": 144,\n \"sha256\": \"6b0a8d6f249bd4fc3f878d37cb5e418680f0f1be2d9eec2518dedf03efc47121\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"public_surface\",\n \"path\": \"crates/event_store/src/lib.rs\",\n \"byte_length\": 3844,\n \"sha256\": \"3cd9653bcb752fb3c4442d4904b98a0a6208011a9a238125b7b7073d7f4e312b\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"migration_registry\",\n \"path\": \"crates/event_store/src/migrations.rs\",\n \"byte_length\": 73585,\n \"sha256\": \"a47477d04759ec6e71d14d3d05459864eae78fce0e3c2481a1b03147f04637f7\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"predecessor_model_public_surface\",\n \"path\": \"crates/event_store/src/model.rs\",\n \"byte_length\": 33596,\n \"sha256\": \"98b1742ffb517f66f8e9edefa61d1c3cf3e22be5985202c6c340310a98c72c8e\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_store_reconciliation_v1_model\",\n \"path\": \"crates/event_store/src/model/reconciliation_v1.rs\",\n \"byte_length\": 11138,\n \"sha256\": \"8a26bc373035878ef9b41767ceea7b681896e17d88bedce118de1d622125e1d6\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"event_store_reconciliation_v1_ingest_model\",\n \"path\": \"crates/event_store/src/model/ingest_reconciliation_v1.rs\",\n \"byte_length\": 1626,\n \"sha256\": \"47bf13b3fc0f8a913a660f7d655413de0f6b90568bc4acc510aa6bd741bab47b\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"addressable_transition_feed_model\",\n \"path\": \"crates/event_store/src/model/addressable_transition_feed_v1.rs\",\n \"byte_length\": 22279,\n \"sha256\": \"f8ea454a0e998a3d433bba52d1ff9759a04fcb91db286cf2a2b10ef7d0057694\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"food_projection_model\",\n \"path\": \"crates/event_store/src/model/food_availability_projection_v1.rs\",\n \"byte_length\": 17482,\n \"sha256\": \"7e8ead52ebfe091e3770878b781a9d089f2f4273f8f57ca0e5c6b12c3ab9acaf\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"source_generation_rebuild_authority\",\n \"path\": \"crates/event_store/src/nip09/reconciliation_v1.rs\",\n \"byte_length\": 184402,\n \"sha256\": \"7fa01e52f51d3470ba60e6068dc05797c2a6eaf5eb317d23111a961dbe4451f9\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"schema_migration_and_reopen_authority\",\n \"path\": \"crates/event_store/src/schema.rs\",\n \"byte_length\": 146146,\n \"sha256\": \"93b060e80d3edd73f86208e4bf698fa9d53eaf1eeb04526c9261fb8b5726fb0d\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"public_store_and_transaction_authority\",\n \"path\": \"crates/event_store/src/store.rs\",\n \"byte_length\": 394777,\n \"sha256\": \"6a2431a6f4b7b5b1d25f493758008ae2246fbe57472552e233fe259404f629a1\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"addressable_transition_feed_store\",\n \"path\": \"crates/event_store/src/store/addressable_transition_feed_v1.rs\",\n \"byte_length\": 40261,\n \"sha256\": \"3b978d2cc7d489b23733d37413824c6fd0bf0c83e3117654939fa856bc8956a3\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"food_projection_store\",\n \"path\": \"crates/event_store/src/store/food_availability_projection_v1.rs\",\n \"byte_length\": 48993,\n \"sha256\": \"91003e69bb6d7a82cc200581089d0e9eb61203a2706e9a3d27286e118b069feb\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"predecessor_post_core_v1_extension\",\n \"path\": \"crates/event_store/src/store/post_core_extensions_v1.rs\",\n \"byte_length\": 6923,\n \"sha256\": \"2fbfc6252f9ce249468a99b5230fd6b7b59b9e47ee4f38783c5fd9379c823fd0\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"predecessor_post_core_v1_storage\",\n \"path\": \"crates/event_store/src/store/post_core_storage_v1.rs\",\n \"byte_length\": 16876,\n \"sha256\": \"f27dc7dcd643762226f8d4df0d297027b384bcf1004277222e978965bc2d40cf\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"raw_ingest_capacity_authority\",\n \"path\": \"crates/event_store/src/store/protocol_reconciliation_v1.rs\",\n \"byte_length\": 30145,\n \"sha256\": \"a8a26763dc39124ab7537fdcc3f89a1f0aa7e1830f4f9dec9ee4057bbb4fd228\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"predecessor_protocol_storage\",\n \"path\": \"crates/event_store/src/store/protocol_storage_v1.rs\",\n \"byte_length\": 10929,\n \"sha256\": \"20de4436945bac0d8cbeca0ae6cd95232a92da8cd6be6ae6beacba17fe50d658\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"source_maintenance_runtime\",\n \"path\": \"crates/event_store/src/source_maintenance_v1.rs\",\n \"byte_length\": 51762,\n \"sha256\": \"5db9c9e86fd18a2fcc08dbc3468f373bf39d8948bc6a08936b252a4dda3546e9\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"artifact_transaction_authority\",\n \"path\": \"tools/xtask/src/contract/artifact_bundle.rs\",\n \"byte_length\": 38279,\n \"sha256\": \"f326ea57b56d40135f95b6b1e15961f66eed363337180a6d12a5ea903e1a9a29\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"predecessor_successor_governance\",\n \"path\": \"tools/xtask/src/contract/food_availability_projection.rs\",\n \"byte_length\": 194572,\n \"sha256\": \"f251b1202c72ae0b63a2f0adee35eb474ba39b9cde7348feee3ab7085d306a11\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"transitive_predecessor_membership_governance\",\n \"path\": \"tools/xtask/src/contract/nip09_reconciliation.rs\",\n \"byte_length\": 835899,\n \"sha256\": \"c37bb32405003775ce34e1379d1197b8c6e330fff96a402612c200a1d206cb38\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"source_maintenance_governance\",\n \"path\": \"tools/xtask/src/contract/source_maintenance.rs\",\n \"byte_length\": 186734,\n \"sha256\": \"0b1d19043d06d6f628f4e92dd11f0b7ec6eb9942ad13a426c5ef78c162b35a6a\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"contract_command_authority\",\n \"path\": \"tools/xtask/src/contract.rs\",\n \"byte_length\": 504371,\n \"sha256\": \"0f8de542e17aa2b1475d5ccb7c38cd35c9132a3390f3c9537ef5de29aa68420f\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n },\n {\n \"role\": \"xtask_dispatch_and_release_preflight\",\n \"path\": \"tools/xtask/src/main.rs\",\n \"byte_length\": 14976,\n \"sha256\": \"42b59a8576e4f86b091941a64349ac9eaa20b1e3b52aef367bb3d5947d8ccd1d\",\n \"hash_algorithm\": \"sha256_bytes_v1\"\n }\n ],\n \"public_api\": {\n \"inherited_predecessor_symbols\": [\n \"RADROOTS_ADDRESSABLE_TRANSITION_CURSOR_JSON_MAX_BYTES_V1\",\n \"RADROOTS_ADDRESSABLE_TRANSITION_D_TAG_MAX_BYTES_V1\",\n \"RADROOTS_ADDRESSABLE_TRANSITION_FEED_VERSION_V1\",\n \"RADROOTS_ADDRESSABLE_TRANSITION_PAGE_LIMIT_MAX_V1\",\n \"RADROOTS_ADDRESSABLE_TRANSITION_PAGE_RAW_JSON_MAX_BYTES_V1\",\n \"RADROOTS_ADDRESSABLE_TRANSITION_PAGE_SCAN_MAX_V1\",\n \"RADROOTS_ADDRESSABLE_TRANSITION_SCOPE_KIND_MAX_V1\",\n \"RADROOTS_FOOD_AVAILABILITY_PROJECTION_APPLY_PAGE_LIMIT_V1\",\n \"RADROOTS_FOOD_AVAILABILITY_PROJECTION_VERSION_V1\",\n \"RADROOTS_FOOD_AVAILABILITY_SEARCH_QUERY_MAX_BYTES_V1\",\n \"RADROOTS_FOOD_AVAILABILITY_SEARCH_QUERY_MAX_TERMS_V1\",\n \"RadrootsAddressableTransitionCauseV1\",\n \"RadrootsAddressableTransitionCoordinateV1\",\n \"RadrootsAddressableTransitionCursorV1\",\n \"RadrootsAddressableTransitionEventReferenceV1\",\n \"RadrootsAddressableTransitionOriginV1\",\n \"RadrootsAddressableTransitionPageV1\",\n \"RadrootsAddressableTransitionRawHeadDecisionV1\",\n \"RadrootsAddressableTransitionScopeFingerprintV1\",\n \"RadrootsAddressableTransitionScopeV1\",\n \"RadrootsAddressableTransitionV1\",\n \"RadrootsAddressableTransitionVisibilityV1\",\n \"RadrootsCurrentEventVisibilityV1\",\n \"RadrootsCurrentVisibilityDecisionV1\",\n \"RadrootsFoodAvailabilitySearchQueryV1\",\n \"RadrootsFoodAvailabilityStatusFilterV1\",\n \"RadrootsNip09SuppressionEvidenceV1\",\n \"RadrootsNip09SuppressionOutcome\",\n \"RadrootsNip09SuppressionReason\",\n \"RadrootsStoreProducedCanonicalEventV1\",\n \"RadrootsStoredFoodAvailabilityImageV1\",\n \"RadrootsStoredFoodAvailabilityV1\"\n ],\n \"added_symbols\": [\n \"RADROOTS_EVENT_STORE_RAW_EVENT_COUNT_LIMIT_V1\",\n \"RADROOTS_EVENT_STORE_RAW_EVENT_TEXT_BYTES_LIMIT_V1\",\n \"RADROOTS_EVENT_STORE_RAW_TAG_COUNT_LIMIT_V1\",\n \"RADROOTS_EVENT_STORE_RAW_TAG_TEXT_BYTES_LIMIT_V1\",\n \"RADROOTS_EVENT_STORE_RETAINED_SOURCE_GENERATION_LIMIT_V1\",\n \"RadrootsEventStoreSourceCapacityResourceV1\",\n \"RadrootsEventStoreSourceCapacityV1\"\n ],\n \"methods\": [\n \"RadrootsEventStore::source_capacity_v1\",\n \"RadrootsEventStoreSourceCapacityResourceV1::as_str\",\n \"RadrootsEventStoreSourceCapacityV1::source_generation\",\n \"RadrootsEventStoreSourceCapacityV1::raw_event_count\",\n \"RadrootsEventStoreSourceCapacityV1::raw_tag_count\",\n \"RadrootsEventStoreSourceCapacityV1::raw_event_text_bytes\",\n \"RadrootsEventStoreSourceCapacityV1::raw_tag_text_bytes\",\n \"RadrootsEventStoreSourceCapacityV1::raw_high_water_seq\",\n \"RadrootsEventStoreSourceCapacityV1::retained_generation_count\",\n \"RadrootsEventStoreSourceCapacityV1::retained_generation_limit\"\n ],\n \"error_variants\": [\n \"SourceCapacityExceeded\",\n \"SourceGenerationHistoryLimitReached\",\n \"PersistedEphemeralRawEvent\",\n \"SourceCapacityStateDrift\",\n \"SqliteMainDatabaseEncodingNotUtf8\",\n \"RollbackWouldDiscardSourceGenerationHistory\"\n ],\n \"removed_symbols\": [\n \"RadrootsEventStoreReconciliationResource\",\n \"RadrootsEventStoreError::ReconciliationCapacityExceeded\"\n ],\n \"breaking_replacements\": [\n {\n \"removed\": \"RadrootsEventStoreReconciliationResource\",\n \"replacement\": \"RadrootsEventStoreSourceCapacityResourceV1\"\n },\n {\n \"removed\": \"RadrootsEventStoreError::ReconciliationCapacityExceeded\",\n \"replacement\": \"RadrootsEventStoreError::SourceCapacityExceeded\"\n }\n ]\n },\n \"result_vector\": {\n \"canonical_path\": \"contracts/conformance/vectors/event_store/source_maintenance.v1.json\",\n \"mirror_path\": \"crates/event_store/tests/fixtures/source_maintenance.v1.json\",\n \"byte_length\": 16253,\n \"sha256\": \"997aba2604a2b9d199fb87dc9d07942ca50d91863aeadcf3eeacf16d191dd71f\",\n \"hash_algorithm\": \"sha256_bytes_v1\",\n \"executor_id\": \"radroots_event_store.source_maintenance_v1.result_vector_executor.v1\",\n \"executor_path\": \"crates/event_store/tests/source_maintenance_v1_result_vector.rs\",\n \"executor_test\": \"source_maintenance_v1_result_vector\",\n \"executor_byte_length\": 23510,\n \"executor_sha256\": \"a7487afdfe19fc5fc794811d0f0e6035203e1aabcf0a33a1d398f6b3555d38f3\",\n \"executor_hash_algorithm\": \"sha256_bytes_v1\"\n }\n}\n"; +pub(crate) const SOURCE_MAINTENANCE_MANIFEST_BYTE_LENGTH: usize = 29764; pub(crate) const SOURCE_MAINTENANCE_MANIFEST_SHA256: &str = - "e3a56e03726af0db35480e55eab9d3244029673cff07bb9e7e1db185125b0785"; + "0723ecb4b332777159e2b01e3ac45381a9c3087ef63e0fd0bf00e4bf0499f328"; pub(crate) const SOURCE_MAINTENANCE_MANIFEST_SCHEMA_VERSION: u32 = 1; pub(crate) const SOURCE_MAINTENANCE_CONTRACT_ID: &str = "radroots_event_store.source_maintenance_v1"; @@ -11,12 +11,12 @@ pub(crate) const SOURCE_MAINTENANCE_MIGRATION_VERSION: u32 = 4; pub(crate) const SOURCE_MAINTENANCE_MIGRATION_NAME: &str = "source_maintenance"; pub(crate) const SOURCE_MAINTENANCE_MIGRATION_UP_BYTE_LENGTH: usize = 19841; pub(crate) const SOURCE_MAINTENANCE_MIGRATION_UP_SHA256: &str = - "425dc799f392b87f265a6fb81f89c4a1c7a5db8391ab0380970708cb9c66704d"; + "ab2724188f8d08c897eebea2533a635e7c74282a25e84e4c0c37e78b08837a43"; pub(crate) const SOURCE_MAINTENANCE_MIGRATION_DOWN_BYTE_LENGTH: usize = 5172; pub(crate) const SOURCE_MAINTENANCE_MIGRATION_DOWN_SHA256: &str = "fe44fd53c51545c08ea479b385e6781079dab70fc63da2a3c205d727a00ce860"; pub(crate) const SOURCE_MAINTENANCE_SCHEMA_SHA256: &str = - "d526d96ea02be12b4b0aed99e97cfdde17c4474ace67111506a7b900ee78b186"; + "074f85b663444ac150239ecd8441ea4a96ad83a798a55e22d2e5e2f7ee943a8c"; pub(crate) const SOURCE_MAINTENANCE_EVENT_CONTRACT_REGISTRY_VERSION: u32 = 7; pub(crate) const SOURCE_MAINTENANCE_CAPACITY_VERSION: u32 = 1; pub(crate) const SOURCE_MAINTENANCE_CAPACITY_AUTHORITY_ID: &str = @@ -45,7 +45,7 @@ pub(crate) const SOURCE_MAINTENANCE_RAW_TAG_TEXT_BYTES_LIMIT: u64 = 33554432; pub(crate) const SOURCE_MAINTENANCE_RETAINED_SOURCE_GENERATION_LIMIT: u32 = 8; pub(crate) const SOURCE_MAINTENANCE_PREDECESSOR_HOOK_ID: &str = "food_availability_projection_v1"; pub(crate) const SOURCE_MAINTENANCE_PREDECESSOR_MANIFEST_SHA256: &str = - "33b93a3c87ce428e8aa6f5e92643c77203d9aa006c53ce96f3562fe6d68ffd23"; + "02dfe1b450fbdac16e718888215b4dd5c85d8975440fa21e8f439fb24c2b2990"; pub(crate) const SOURCE_MAINTENANCE_RESULT_VECTOR_SHA256: &str = "997aba2604a2b9d199fb87dc9d07942ca50d91863aeadcf3eeacf16d191dd71f"; pub(crate) const SOURCE_MAINTENANCE_RESULT_VECTOR_EXECUTOR_ID: &str = diff --git a/crates/event_store/src/model.rs b/crates/event_store/src/model.rs @@ -36,10 +36,11 @@ pub use food_availability_projection_v1::{ use crate::RadrootsEventStoreError; use radroots_event::RadrootsEventKind; use radroots_event::ids::{ - RadrootsDTag, RadrootsEventId, RadrootsInventoryBinId, RadrootsPublicKey, - RadrootsTradeCandidateId, RadrootsTradeId, RadrootsTradeMutationId, + RadrootsDTag, RadrootsEventId, RadrootsInventoryBinId, RadrootsTradeCandidateId, + RadrootsTradeId, RadrootsTradeMutationId, }; use radroots_event::trade::RadrootsTradeMutationKindV1; +use radroots_identity::PublicKey; use radroots_transport::{ RadrootsTransportKind, RadrootsTransportTarget, RadrootsTransportTargetFingerprint, RadrootsTransportTargetUri, @@ -510,10 +511,10 @@ pub struct RadrootsStoredTradeMutation { pub candidate_id: Option<RadrootsTradeCandidateId>, pub proposal_mutation_id: Option<RadrootsTradeMutationId>, pub target_claim_mutation_id: Option<RadrootsTradeMutationId>, - pub author_pubkey: RadrootsPublicKey, - pub counterparty_pubkey: RadrootsPublicKey, - pub buyer_pubkey: RadrootsPublicKey, - pub seller_pubkey: RadrootsPublicKey, + pub author_pubkey: PublicKey, + pub counterparty_pubkey: PublicKey, + pub buyer_pubkey: PublicKey, + pub seller_pubkey: PublicKey, pub farm_id: RadrootsDTag, pub authored_at_unix_s: u64, pub canonical_payload_bytes: Vec<u8>, @@ -545,7 +546,7 @@ pub struct RadrootsStoredTradeTransportEnvelope { pub mutation_id: RadrootsTradeMutationId, pub trade_id: RadrootsTradeId, pub transport_kind: String, - pub pubkey: RadrootsPublicKey, + pub pubkey: PublicKey, pub created_at: u64, pub event_seq: i64, pub payload_sha256: String, @@ -558,7 +559,7 @@ pub struct RadrootsStoredSellerReservation { pub trade_id: RadrootsTradeId, pub candidate_id: RadrootsTradeCandidateId, pub claim_mutation_id: RadrootsTradeMutationId, - pub inventory_authority_pubkey: RadrootsPublicKey, + pub inventory_authority_pubkey: PublicKey, pub inventory_epoch: u64, pub assertion_commitment: String, pub reservation_expires_at_unix_s: u64, @@ -607,7 +608,8 @@ mod tests { use radroots_event::event_head::{ RadrootsCurrentEventHead, RadrootsEventHeadCoordinate, RadrootsEventHeadDecision, }; - use radroots_event::ids::{RadrootsEventId, RadrootsPublicKey}; + use radroots_event::ids::RadrootsEventId; + use radroots_identity::PublicKey; #[test] fn admission_status_event_class_and_observation_values_roundtrip() { @@ -798,7 +800,7 @@ mod tests { fn head_decisions_and_tag_metadata_names_cover_all_variants() { let coordinate = RadrootsEventHeadCoordinate::Addressable { kind: 30_023, - pubkey: RadrootsPublicKey::parse( + pubkey: PublicKey::from_hex( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", ) .expect("pubkey"), diff --git a/crates/event_store/src/model/addressable_transition_feed_v1.rs b/crates/event_store/src/model/addressable_transition_feed_v1.rs @@ -3,7 +3,8 @@ use super::{ RadrootsNip09SuppressionEvidenceV1, }; use crate::RadrootsEventStoreError; -use radroots_event::ids::{RadrootsEventId, RadrootsPublicKey}; +use radroots_event::ids::RadrootsEventId; +use radroots_identity::PublicKey; use serde::{Deserialize, Serialize}; use sha2::{Digest, Sha256}; use std::collections::BTreeSet; @@ -289,7 +290,7 @@ pub struct RadrootsAddressableTransitionEventReferenceV1 { #[derive(Clone, Debug, PartialEq, Eq)] pub struct RadrootsAddressableTransitionCauseV1 { pub(crate) event: RadrootsAddressableTransitionEventReferenceV1, - pub(crate) pubkey: RadrootsPublicKey, + pub(crate) pubkey: PublicKey, pub(crate) created_at: u64, pub(crate) kind: u32, pub(crate) admission_status: RadrootsEventAdmissionStatus, @@ -302,7 +303,7 @@ impl RadrootsAddressableTransitionCauseV1 { &self.event } - pub const fn pubkey(&self) -> &RadrootsPublicKey { + pub const fn pubkey(&self) -> &PublicKey { &self.pubkey } @@ -336,7 +337,7 @@ impl RadrootsAddressableTransitionCauseV1 { #[derive(Clone, Debug, PartialEq, Eq)] pub struct RadrootsAddressableTransitionCoordinateV1 { pub(crate) kind: u32, - pub(crate) pubkey: RadrootsPublicKey, + pub(crate) pubkey: PublicKey, pub(crate) d_tag: String, } @@ -345,7 +346,7 @@ impl RadrootsAddressableTransitionCoordinateV1 { self.kind } - pub const fn pubkey(&self) -> &RadrootsPublicKey { + pub const fn pubkey(&self) -> &PublicKey { &self.pubkey } @@ -373,7 +374,7 @@ impl RadrootsAddressableTransitionEventReferenceV1 { #[derive(Clone, Debug, PartialEq, Eq)] pub struct RadrootsStoreProducedCanonicalEventV1 { pub(crate) event_id: RadrootsEventId, - pub(crate) pubkey: RadrootsPublicKey, + pub(crate) pubkey: PublicKey, pub(crate) created_at: u64, pub(crate) kind: u32, pub(crate) raw_json: String, @@ -384,7 +385,7 @@ impl RadrootsStoreProducedCanonicalEventV1 { &self.event_id } - pub const fn pubkey(&self) -> &RadrootsPublicKey { + pub const fn pubkey(&self) -> &PublicKey { &self.pubkey } diff --git a/crates/event_store/src/model/food_availability_projection_v1.rs b/crates/event_store/src/model/food_availability_projection_v1.rs @@ -9,12 +9,13 @@ use radroots_event::{ RadrootsFoodIdentifier, RadrootsFoodImageDimensions, RadrootsFoodPrice, RadrootsFoodPublishedAt, RadrootsFoodQuantity, RadrootsFoodText, food_media_blossom_digest, }, - ids::{RadrootsEventId, RadrootsPublicKey}, + ids::RadrootsEventId, }; use radroots_event_codec::food_availability::inbound::{ RadrootsFoodAvailabilityImageDiagnostic, RadrootsInboundFoodAvailabilityImage, RadrootsInboundFoodAvailabilityProjection, }; +use radroots_identity::PublicKey; pub const RADROOTS_FOOD_AVAILABILITY_PROJECTION_VERSION_V1: u32 = 1; pub const RADROOTS_FOOD_AVAILABILITY_PROJECTION_APPLY_PAGE_LIMIT_V1: u32 = @@ -220,7 +221,7 @@ impl RadrootsStoredFoodAvailabilityImageV1 { #[derive(Clone, Debug, PartialEq, Eq)] pub struct RadrootsStoredFoodAvailabilityV1 { source_generation: RadrootsEventStoreSourceGeneration, - pubkey: RadrootsPublicKey, + pubkey: PublicKey, identifier: RadrootsFoodIdentifier, event_id: RadrootsEventId, event_seq: i64, @@ -242,7 +243,7 @@ impl RadrootsStoredFoodAvailabilityV1 { #[allow(clippy::too_many_arguments)] pub(crate) fn from_projection( source_generation: RadrootsEventStoreSourceGeneration, - pubkey: RadrootsPublicKey, + pubkey: PublicKey, event_id: RadrootsEventId, event_seq: i64, created_at: u64, @@ -313,7 +314,7 @@ impl RadrootsStoredFoodAvailabilityV1 { self.source_generation } - pub const fn pubkey(&self) -> &RadrootsPublicKey { + pub const fn pubkey(&self) -> &PublicKey { &self.pubkey } diff --git a/crates/event_store/src/nip09/reconciliation_v1.rs b/crates/event_store/src/nip09/reconciliation_v1.rs @@ -412,7 +412,7 @@ impl<'a> RequestIndex<'a> { address_targets .entry(( i64::from(target.coordinate().kind()), - target.coordinate().pubkey().as_str().to_owned(), + target.coordinate().pubkey().to_hex(), target.coordinate().identifier().to_owned(), )) .or_default() @@ -1476,7 +1476,11 @@ async fn load_reconciliation_snapshot( .map_err(|_| raw_mismatch(event_id.as_str(), "raw_json"))?; let event = ingest.event(); compare_raw_field(event.id_str() == event_id, event_id.as_str(), "event_id")?; - compare_raw_field(event.author_str() == pubkey, event_id.as_str(), "pubkey")?; + compare_raw_field( + event.author().to_hex() == pubkey, + event_id.as_str(), + "pubkey", + )?; let created_at: i64 = row.try_get("created_at")?; compare_raw_field( i64::try_from(event.created_at_u64()).ok() == Some(created_at), @@ -1876,7 +1880,7 @@ async fn rebuild_raw_heads( "INSERT INTO event_envelope_head(coordinate_type, kind, pubkey, d_tag, event_id, created_at, updated_at_ms) VALUES ('replaceable', ?, ?, NULL, ?, ?, ?)", ) .bind(i64::from(*kind)) - .bind(pubkey.as_str()) + .bind(pubkey.to_hex()) .bind(winner.candidate.event_id.as_str()) .bind(i64_from_u64( "raw_head_created_at", @@ -1895,7 +1899,7 @@ async fn rebuild_raw_heads( "INSERT INTO event_envelope_head(coordinate_type, kind, pubkey, d_tag, event_id, created_at, updated_at_ms) VALUES ('addressable', ?, ?, ?, ?, ?, ?)", ) .bind(i64::from(*kind)) - .bind(pubkey.as_str()) + .bind(pubkey.to_hex()) .bind(d_tag) .bind(winner.candidate.event_id.as_str()) .bind(i64_from_u64( @@ -2033,35 +2037,36 @@ fn event_coordinate_fact( ) -> Result<Option<EventCoordinateFact>, RadrootsEventStoreError> { let envelope = event.verified_event.event(); let kind = envelope.kind_u32(); - let (coordinate_type, raw_d_tag, nip09_d_tag) = - if matches!(kind, 0 | 3) || (10_000..=19_999).contains(&kind) { - ("replaceable", String::new(), Some(String::new())) - } else if (30_000..=39_999).contains(&kind) { - let raw_d_tag_value = envelope - .tag_slices() - .iter() - .find(|tag| tag.as_slice().first().is_some_and(|name| name == "d")) - .and_then(|tag| tag.as_slice().get(1)) - .cloned(); - let nip09_d_tag = raw_d_tag_value.as_ref().and_then(|d_tag| { - RadrootsNip01Coordinate::parse(format!("{kind}:{}:{d_tag}", envelope.author_str())) - .ok() - .map(|coordinate| coordinate.identifier().to_owned()) - }); - ( - "addressable", - raw_d_tag_value.unwrap_or_default(), - nip09_d_tag, - ) - } else { - return Ok(None); - }; + let (coordinate_type, raw_d_tag, nip09_d_tag) = if matches!(kind, 0 | 3) + || (10_000..=19_999).contains(&kind) + { + ("replaceable", String::new(), Some(String::new())) + } else if (30_000..=39_999).contains(&kind) { + let raw_d_tag_value = envelope + .tag_slices() + .iter() + .find(|tag| tag.as_slice().first().is_some_and(|name| name == "d")) + .and_then(|tag| tag.as_slice().get(1)) + .cloned(); + let nip09_d_tag = raw_d_tag_value.as_ref().and_then(|d_tag| { + RadrootsNip01Coordinate::parse(format!("{kind}:{}:{d_tag}", envelope.author().to_hex())) + .ok() + .map(|coordinate| coordinate.identifier().to_owned()) + }); + ( + "addressable", + raw_d_tag_value.unwrap_or_default(), + nip09_d_tag, + ) + } else { + return Ok(None); + }; Ok(Some(EventCoordinateFact { event_id: envelope.id_str().to_owned(), event_seq: event.seq, coordinate_type: coordinate_type.to_owned(), kind: i64::from(kind), - pubkey: envelope.author_str().to_owned(), + pubkey: envelope.author().to_hex().to_owned(), created_at: i64_from_u64("created_at", envelope.created_at_u64())?, inserted_at_ms: event.inserted_at_ms, admission_status: event.admission.status.as_str().to_owned(), @@ -2151,7 +2156,7 @@ async fn validate_nip09_fact_graph( expected_requests.insert(RequestFact { request_event_id: request.event().id_str().to_owned(), request_event_seq: event.seq, - request_pubkey: request.event().author_str().to_owned(), + request_pubkey: request.event().author().to_hex().to_owned(), request_created_at: i64_from_u64( "request_created_at", request.event().created_at_u64(), @@ -2175,7 +2180,7 @@ async fn validate_nip09_fact_graph( expected_address_targets.insert(AddressTargetFact { request_event_id: request.event().id_str().to_owned(), target_kind: i64::from(target.coordinate().kind()), - target_pubkey: target.coordinate().pubkey().as_str().to_owned(), + target_pubkey: target.coordinate().pubkey().to_hex(), target_d_tag: target.coordinate().identifier().to_owned(), inclusive_cutoff: i64_from_u64( "inclusive_cutoff", @@ -2326,7 +2331,7 @@ async fn persist_request_fact( .bind(generation.as_bytes().as_slice()) .bind(event.id_str()) .bind(request_seq) - .bind(event.author_str()) + .bind(event.author().to_hex()) .bind(i64_from_u64( "request_created_at", event.created_at_u64(), @@ -2358,7 +2363,7 @@ async fn persist_request_fact( .bind(generation.as_bytes().as_slice()) .bind(event.id_str()) .bind(i64::from(target.coordinate().kind())) - .bind(target.coordinate().pubkey().as_str()) + .bind(target.coordinate().pubkey().to_hex()) .bind(target.coordinate().identifier()) .bind(i64_from_u64("inclusive_cutoff", event.created_at_u64())?) .bind(i64_from_usize("source_tag_index", target.tag_index())?) @@ -2605,7 +2610,7 @@ fn desired_addressable_states( })?; let state = addressable_state_for_event( i64::from(kind), - pubkey.as_str(), + &pubkey.to_hex(), d_tag.as_str(), winner.event_seq, event, @@ -2876,7 +2881,7 @@ fn expected_transition_history( field: "transition.kind", value: kind, })?, - pubkey: radroots_event::ids::RadrootsPublicKey::parse(pubkey.as_str())?, + pubkey: radroots_identity::PublicKey::from_hex(pubkey.as_str())?, d_tag: d_tag.clone(), }; let winner = winners.get(&coordinate).ok_or_else(|| { @@ -2974,7 +2979,7 @@ fn request_references_event( || nip01_coordinate_key(event).is_some_and(|(kind, pubkey, d_tag)| { request.projection().address_targets().iter().any(|target| { i64::from(target.coordinate().kind()) == kind - && target.coordinate().pubkey().as_str() == pubkey + && target.coordinate().pubkey().to_hex() == pubkey && target.coordinate().identifier() == d_tag }) }) @@ -4251,7 +4256,7 @@ INSERT INTO caller_child(id, parent_id) VALUES (1, 999);", "INSERT INTO event_envelopes(event_id, pubkey, created_at, kind, tags_json, content, sig, raw_json, verification_status, contract_status, contract_id, event_class, projection_eligible, inserted_at_ms, updated_at_ms) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'verified', ?, ?, ?, ?, ?, ?)", ) .bind(event.id_str()) - .bind(event.author_str()) + .bind(event.author().to_hex()) .bind(i64::try_from(event.created_at_u64()).expect("created_at")) .bind(i64::from(event.kind_u32())) .bind(tags_json) @@ -4306,7 +4311,7 @@ INSERT INTO caller_child(id, parent_id) VALUES (1, 999);", ) -> RadrootsEventIngest { let wire = RadrootsNip01EventWire { id: envelope.id_str().to_owned(), - pubkey: envelope.author_str().to_owned(), + pubkey: envelope.author().to_hex().to_owned(), created_at: envelope.created_at_u64(), kind: envelope.kind_u32(), tags: envelope.tags_as_vec(), @@ -4443,7 +4448,7 @@ INSERT INTO caller_child(id, parent_id) VALUES (1, 999);", "INSERT INTO event_envelopes(event_id, pubkey, created_at, kind, tags_json, content, sig, raw_json, verification_status, contract_status, contract_id, event_class, projection_eligible, inserted_at_ms, updated_at_ms) VALUES (?, ?, ?, ?, '[]', ?, ?, ?, 'verified', ?, ?, ?, ?, ?, ?)", ) .bind(event.id_str()) - .bind(event.author_str()) + .bind(event.author().to_hex()) .bind(i64::try_from(event.created_at_u64()).expect("created_at")) .bind(i64::from(event.kind_u32())) .bind(event.content()) diff --git a/crates/event_store/src/nip09/reconciliation_v1/result_vector_executor.rs b/crates/event_store/src/nip09/reconciliation_v1/result_vector_executor.rs @@ -228,7 +228,7 @@ async fn seed_v1_raw_event( "INSERT INTO event_envelopes(event_id, pubkey, created_at, kind, tags_json, content, sig, raw_json, verification_status, contract_status, contract_id, event_class, projection_eligible, inserted_at_ms, updated_at_ms) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'verified', ?, ?, ?, ?, ?, ?)", ) .bind(event.id_str()) - .bind(event.author_str()) + .bind(event.author().to_hex()) .bind( i64::try_from(event.created_at_u64()) .unwrap_or_else(|_| panic!("{case_id}: created_at exceeds SQLite range")), diff --git a/crates/event_store/src/source_maintenance_v1.rs b/crates/event_store/src/source_maintenance_v1.rs @@ -81,7 +81,7 @@ pub(crate) fn raw_source_capacity_delta_v1( let event = ingest.event(); let raw_event_bytes = raw_event_row_bytes_v1( event.id_str(), - event.author_str(), + &event.author().to_hex(), tags_json, event.content(), event.sig_str(), diff --git a/crates/event_store/src/store.rs b/crates/event_store/src/store.rs @@ -1721,14 +1721,16 @@ fn bool_from_i64(field: &'static str, value: i64) -> Result<bool, RadrootsEventS fn parse_id<T>(value: String) -> Result<T, RadrootsEventStoreError> where - T: TryFrom<String, Error = radroots_event::ids::RadrootsIdParseError>, + T: TryFrom<String>, + T::Error: Into<RadrootsEventStoreError>, { T::try_from(value).map_err(Into::into) } fn parse_optional_id<T>(value: Option<String>) -> Result<Option<T>, RadrootsEventStoreError> where - T: TryFrom<String, Error = radroots_event::ids::RadrootsIdParseError>, + T: TryFrom<String>, + T::Error: Into<RadrootsEventStoreError>, { value.map(parse_id).transpose() } @@ -1787,9 +1789,7 @@ mod tests { use radroots_event::food_availability::{ RadrootsFoodAvailabilityStatus, RadrootsFoodIdentifier, }; - use radroots_event::ids::{ - RadrootsClassifiedListingAddress, RadrootsInventoryBinId, RadrootsPublicKey, - }; + use radroots_event::ids::{RadrootsClassifiedListingAddress, RadrootsInventoryBinId}; use radroots_event::kinds::{ KIND_CALENDAR_DATE_EVENT, KIND_CLASSIFIED_LISTING, KIND_DELETION_REQUEST, KIND_FARM, KIND_GEOCHAT, KIND_LIST_SET_RELAY, KIND_POST, KIND_PROFILE, KIND_RELAY_AUTH, @@ -1809,12 +1809,15 @@ mod tests { compute_canonical_nip01_event_id, }; use radroots_event_codec::food_availability::inbound::RadrootsFoodAvailabilityImageDiagnostic; + use radroots_identity::PublicKey; use std::sync::Arc; const FIXTURE_ALICE_SECRET_KEY_HEX: &str = "10c5304d6c9ae3a1a16f7860f1cc8f5e3a76225a2663b3a989a0d775919b7df5"; const FIXTURE_ALICE_PUBLIC_KEY_HEX: &str = "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df"; + const FIXTURE_BOB_PUBLIC_KEY_HEX: &str = + "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"; struct FixedGeneration([u8; 32]); @@ -1893,11 +1896,13 @@ mod tests { RadrootsTradeId::parse("1".repeat(32)).expect("trade id") } - fn public_key(character: char) -> RadrootsPublicKey { - if character == 'a' { - return RadrootsPublicKey::parse(FIXTURE_ALICE_PUBLIC_KEY_HEX).expect("alice pubkey"); - } - RadrootsPublicKey::parse(event_id(character)).expect("pubkey") + fn public_key(character: char) -> PublicKey { + let public_key_hex = match character { + 'a' => FIXTURE_ALICE_PUBLIC_KEY_HEX, + 'b' => FIXTURE_BOB_PUBLIC_KEY_HEX, + _ => panic!("unsupported fixture public key label: {character}"), + }; + PublicKey::from_hex(public_key_hex).expect("fixture pubkey") } fn candidate_terms() -> RadrootsTradeCandidateTermsV1 { @@ -2038,7 +2043,7 @@ mod tests { content: String, keys: &RadrootsNostrKeys, ) -> RadrootsSignedEvent { - let counterparty = canonical.envelope.counterparty_pubkey.as_str().to_owned(); + let counterparty = canonical.envelope.counterparty_pubkey.to_hex(); let mut tags = vec![ vec![ "contract".to_owned(), @@ -2094,9 +2099,10 @@ mod tests { fn raw_source_text_bytes(event: &RadrootsSignedEvent) -> (u64, u64) { let tags = event.tags_as_vec(); let tags_json = serde_json::to_string(&tags).expect("tags JSON"); + let pubkey = event.pubkey().to_hex(); let event_bytes = [ event.id_str(), - event.pubkey_str(), + pubkey.as_str(), tags_json.as_str(), event.content(), event.sig_str(), @@ -2284,7 +2290,7 @@ mod tests { fn profile_coordinate() -> RadrootsEventHeadCoordinate { RadrootsEventHeadCoordinate::Replaceable { kind: KIND_PROFILE, - pubkey: RadrootsPublicKey::parse(FIXTURE_ALICE_PUBLIC_KEY_HEX).expect("pubkey"), + pubkey: PublicKey::from_hex(FIXTURE_ALICE_PUBLIC_KEY_HEX).expect("pubkey"), } } @@ -2725,7 +2731,7 @@ mod tests { "INSERT INTO event_envelopes(event_id, pubkey, created_at, kind, tags_json, content, sig, raw_json, verification_status, contract_status, contract_id, event_class, projection_eligible, inserted_at_ms, updated_at_ms) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'verified', 'admitted', 'radroots.post.v1', 'regular', 1, ?, ?)", ) .bind(event.id_str()) - .bind(event.author_str()) + .bind(event.author().to_hex()) .bind(i64::try_from(event.created_at_u64()).expect("created_at")) .bind(i64::from(event.kind_u32())) .bind(tags_json) @@ -2995,7 +3001,7 @@ mod tests { assert_eq!(cursor_generation, target_generation); let projected = store .food_availability_v1( - &RadrootsPublicKey::parse(FIXTURE_ALICE_PUBLIC_KEY_HEX).expect("author"), + &PublicKey::from_hex(FIXTURE_ALICE_PUBLIC_KEY_HEX).expect("author"), &RadrootsFoodIdentifier::parse("v4-rebuild-carrots").expect("identifier"), ) .await @@ -3125,7 +3131,7 @@ mod tests { let raw_digest = raw_authority_digest(&store).await; let projected = store .food_availability_v1( - &RadrootsPublicKey::parse(FIXTURE_ALICE_PUBLIC_KEY_HEX).expect("author"), + &PublicKey::from_hex(FIXTURE_ALICE_PUBLIC_KEY_HEX).expect("author"), &RadrootsFoodIdentifier::parse("migration-carrots").expect("identifier"), ) .await @@ -3177,7 +3183,7 @@ mod tests { assert_eq!(raw_authority_digest(&store).await, raw_digest); let rebuilt = store .food_availability_v1( - &RadrootsPublicKey::parse(FIXTURE_ALICE_PUBLIC_KEY_HEX).expect("author"), + &PublicKey::from_hex(FIXTURE_ALICE_PUBLIC_KEY_HEX).expect("author"), &RadrootsFoodIdentifier::parse("migration-carrots").expect("identifier"), ) .await @@ -5995,7 +6001,7 @@ CREATE TABLE aux.event_transport_observation (event_id TEXT);", ); assert!(seller_reservation_for_mutation(&revision_decision).is_some()); assert!(seller_reservation_for_mutation(&cancellation).is_none()); - assert_eq!(public_key('b').as_str(), event_id('b')); + assert_eq!(public_key('b').to_hex(), FIXTURE_BOB_PUBLIC_KEY_HEX); for kind in [ RadrootsTradeMutationKindV1::Proposal, @@ -6619,7 +6625,7 @@ CREATE TABLE aux.event_transport_observation (event_id TEXT);", .expect("sealed projection count"); assert_eq!(initial_projection_count, 2); - let author = RadrootsPublicKey::parse(FIXTURE_ALICE_PUBLIC_KEY_HEX).expect("author"); + let author = PublicKey::from_hex(FIXTURE_ALICE_PUBLIC_KEY_HEX).expect("author"); let carrot_id = RadrootsFoodIdentifier::parse("nantes-carrots").expect("identifier"); let projected = store .food_availability_v1(&author, &carrot_id) @@ -7259,7 +7265,7 @@ CREATE TABLE aux.event_transport_observation (event_id TEXT);", "active", Vec::new(), ); - let author = RadrootsPublicKey::parse(FIXTURE_ALICE_PUBLIC_KEY_HEX).expect("author"); + let author = PublicKey::from_hex(FIXTURE_ALICE_PUBLIC_KEY_HEX).expect("author"); let identifier = RadrootsFoodIdentifier::parse("nantes-carrots").expect("identifier"); for (observed_at_ms, event) in [(20_000, &active), (20_001, &sold)] { @@ -7370,7 +7376,7 @@ CREATE TABLE aux.event_transport_observation (event_id TEXT);", deletion.id_str() ); assert_eq!( - deletion_cause.pubkey().as_str(), + &deletion_cause.pubkey().to_hex(), FIXTURE_ALICE_PUBLIC_KEY_HEX ); assert_eq!(deletion_cause.created_at(), 230); @@ -7421,7 +7427,7 @@ CREATE TABLE aux.event_transport_observation (event_id TEXT);", let store = RadrootsEventStore::open_memory().await.expect("open"); let identifier = RadrootsFoodIdentifier::parse("AAAAAAAAAAAAAAAAAAAAAg").expect("identifier"); - let author = RadrootsPublicKey::parse(FIXTURE_ALICE_PUBLIC_KEY_HEX).expect("author"); + let author = PublicKey::from_hex(FIXTURE_ALICE_PUBLIC_KEY_HEX).expect("author"); let food = food_availability_event( 200, identifier.as_str(), @@ -7544,7 +7550,7 @@ CREATE TABLE aux.event_transport_observation (event_id TEXT);", "active", Vec::new(), ); - let author = RadrootsPublicKey::parse(FIXTURE_ALICE_PUBLIC_KEY_HEX).expect("author"); + let author = PublicKey::from_hex(FIXTURE_ALICE_PUBLIC_KEY_HEX).expect("author"); let identifier = RadrootsFoodIdentifier::parse("rollback-carrots").expect("identifier"); let mut transaction = store.begin_write_transaction().await.expect("transaction"); @@ -7640,7 +7646,7 @@ CREATE TABLE aux.event_transport_observation (event_id TEXT);", .await .expect("wrong-author deletion remains a valid event"); - let author = RadrootsPublicKey::parse(FIXTURE_ALICE_PUBLIC_KEY_HEX).expect("author"); + let author = PublicKey::from_hex(FIXTURE_ALICE_PUBLIC_KEY_HEX).expect("author"); let identifier = RadrootsFoodIdentifier::parse("protected-carrots").expect("identifier"); let projection = store .food_availability_v1(&author, &identifier) diff --git a/crates/event_store/src/store/addressable_transition_feed_v1.rs b/crates/event_store/src/store/addressable_transition_feed_v1.rs @@ -20,7 +20,8 @@ use crate::model::{ use crate::nip09::reconciliation_v1::{ EventAdmission, ReconciliationProfile, generation_from_blob, }; -use radroots_event::ids::{RadrootsEventId, RadrootsPublicKey}; +use radroots_event::ids::RadrootsEventId; +use radroots_identity::PublicKey; use sqlx::{QueryBuilder, Row, Sqlite, SqliteConnection}; impl RadrootsEventStore { @@ -337,7 +338,7 @@ async fn transition_from_row( } let coordinate = RadrootsAddressableTransitionCoordinateV1 { kind, - pubkey: RadrootsPublicKey::parse(pubkey.as_str()) + pubkey: PublicKey::from_hex(pubkey.as_str()) .map_err(|error| corruption(format!("transition pubkey is invalid: {error}")))?, d_tag, }; @@ -493,7 +494,7 @@ async fn transition_from_row( let event_reference = cause_reference .clone() .ok_or_else(|| corruption("loaded transition cause has no reference"))?; - let pubkey = RadrootsPublicKey::parse(event.pubkey.as_str()).map_err(|error| { + let pubkey = PublicKey::from_hex(event.pubkey.as_str()).map_err(|error| { corruption(format!("transition cause pubkey is invalid: {error}")) })?; Ok::<RadrootsAddressableTransitionCauseV1, RadrootsEventStoreError>( @@ -575,7 +576,7 @@ async fn validate_incremental_cause( "non-head incremental transition was not caused by an admitted deletion request", )); } - let author_matches = cause_event.pubkey == coordinate.pubkey().as_str(); + let author_matches = cause_event.pubkey == coordinate.pubkey().to_hex(); let records_author_mismatch = suppression.is_some_and(|evidence| { evidence.reason() == crate::model::RadrootsNip09SuppressionReason::RequestAuthorMismatch @@ -594,7 +595,7 @@ async fn validate_incremental_cause( .bind(generation.as_bytes().as_slice()) .bind(cause_reference.event_id().as_str()) .bind(i64::from(coordinate.kind())) - .bind(coordinate.pubkey().as_str()) + .bind(coordinate.pubkey().to_hex()) .bind(coordinate.d_tag()) .fetch_one(&mut *connection) .await?; @@ -632,7 +633,7 @@ async fn validate_retraction_lineage( ) .bind(generation.as_bytes().as_slice()) .bind(i64::from(coordinate.kind())) - .bind(coordinate.pubkey().as_str()) + .bind(coordinate.pubkey().to_hex()) .bind(coordinate.d_tag()) .bind(transition_seq) .fetch_optional(&mut *connection) @@ -883,7 +884,7 @@ async fn load_and_validate_stored_event( )) })?; if stored.event_id != event.id_str() - || stored.pubkey != event.author_str() + || stored.pubkey != event.author().to_hex() || stored.created_at != event.created_at_u64() || stored.kind != event.kind_u32() || stored.tags_json != tags_json @@ -921,7 +922,7 @@ async fn validate_addressable_reference( ) -> Result<(), RadrootsEventStoreError> { if event.event_class != StoredEventClass::Addressable || event.kind != coordinate.kind() - || event.pubkey != coordinate.pubkey().as_str() + || event.pubkey != coordinate.pubkey().to_hex() { return Err(corruption(format!( "event `{}` does not match transition coordinate `{}:{}:{}`", @@ -938,7 +939,7 @@ async fn validate_addressable_reference( .bind(reference.event_seq()) .bind(reference.event_id().as_str()) .bind(i64::from(coordinate.kind())) - .bind(coordinate.pubkey().as_str()) + .bind(coordinate.pubkey().to_hex()) .bind(coordinate.d_tag()) .fetch_one(&mut *connection) .await?; diff --git a/crates/event_store/src/store/food_availability_projection_v1.rs b/crates/event_store/src/store/food_availability_projection_v1.rs @@ -17,11 +17,12 @@ use crate::nip09::reconciliation_v1::{ EventAdmission, ReconciliationProfile, generation_from_blob, }; use radroots_event::food_availability::RadrootsFoodIdentifier; -use radroots_event::ids::{RadrootsEventId, RadrootsPublicKey}; +use radroots_event::ids::RadrootsEventId; use radroots_event_codec::food_availability::inbound::{ RadrootsFoodAvailabilityImageDiagnostic, RadrootsFoodAvailabilityProjectionOutcome, project_verified_food_availability_event_registry_v7, }; +use radroots_identity::PublicKey; use serde::Deserialize; use sqlx::{Row, SqliteConnection}; @@ -50,13 +51,13 @@ struct FoodAvailabilityProjectionCursorState { impl RadrootsEventStore { pub async fn food_availability_v1( &self, - pubkey: &RadrootsPublicKey, + pubkey: &PublicKey, identifier: &RadrootsFoodIdentifier, ) -> Result<Option<RadrootsStoredFoodAvailabilityV1>, RadrootsEventStoreError> { let mut tx = self.pool.begin().await?; validate_food_availability_projection_hook_state_fast_v1(&mut tx).await?; let row = sqlx::query(FOOD_AVAILABILITY_POINT_QUERY_V1) - .bind(pubkey.as_str()) + .bind(pubkey.to_hex()) .bind(identifier.as_str()) .fetch_optional(&mut *tx) .await?; @@ -335,7 +336,7 @@ async fn apply_transition( "SELECT event_id FROM radroots_event_store_food_availability_projection WHERE source_generation = ? AND pubkey = ? AND d_tag = ?", ) .bind(transition.source_generation().as_bytes().as_slice()) - .bind(coordinate.pubkey().as_str()) + .bind(coordinate.pubkey().to_hex()) .bind(coordinate.d_tag()) .fetch_optional(&mut *connection) .await?; @@ -349,7 +350,7 @@ async fn apply_transition( "DELETE FROM radroots_event_store_food_availability_projection WHERE source_generation = ? AND pubkey = ? AND d_tag = ? AND event_id = ?", ) .bind(transition.source_generation().as_bytes().as_slice()) - .bind(coordinate.pubkey().as_str()) + .bind(coordinate.pubkey().to_hex()) .bind(coordinate.d_tag()) .bind(retracted.event_id().as_str()) .execute(&mut *connection) @@ -404,7 +405,7 @@ async fn apply_transition( }; let event = ingest.event(); if canonical.event_id().as_str() != event.id_str() - || canonical.pubkey().as_str() != event.author_str() + || canonical.pubkey() != event.author() || canonical.created_at() != event.created_at_u64() || canonical.kind() != event.kind_u32() { @@ -440,7 +441,7 @@ async fn persist_projection( "INSERT INTO radroots_event_store_food_availability_projection(source_generation, kind, pubkey, d_tag, event_id, event_seq, created_at, contract_id, content, title, summary, published_at, location, price_amount, price_currency, price_unit, quantity_amount, quantity_unit, status, diagnostic_codes_json, source_transition_seq) VALUES (?, 30402, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", ) .bind(projection.source_generation().as_bytes().as_slice()) - .bind(projection.pubkey().as_str()) + .bind(projection.pubkey().to_hex()) .bind(projection.identifier().as_str()) .bind(projection.event_id().as_str()) .bind(projection.event_seq()) @@ -487,7 +488,7 @@ async fn persist_image( "INSERT INTO radroots_event_store_food_availability_image(source_generation, pubkey, d_tag, image_index, raw_tag_json, url, width, height, blossom_sha256, qualifies, diagnostic_codes_json) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", ) .bind(projection.source_generation().as_bytes().as_slice()) - .bind(projection.pubkey().as_str()) + .bind(projection.pubkey().to_hex()) .bind(projection.identifier().as_str()) .bind(i64::from(image.image_index())) .bind(raw_tag_json) @@ -525,7 +526,7 @@ pub(crate) async fn validate_food_availability_projection_hook_v1( validate_projection_source_transition(connection, &projection).await?; validate_fts_row(connection, &projection).await?; actual_coordinates.push(( - projection.pubkey().as_str().to_owned(), + projection.pubkey().to_hex(), projection.identifier().as_str().to_owned(), projection.event_id().as_str().to_owned(), projection.event_seq(), @@ -594,7 +595,7 @@ async fn validate_projection_source_transition( ) .bind(projection.source_transition_seq()) .bind(projection.source_generation().as_bytes().as_slice()) - .bind(projection.pubkey().as_str()) + .bind(projection.pubkey().to_hex()) .bind(projection.identifier().as_str()) .bind(projection.event_id().as_str()) .bind(projection.event_seq()) @@ -702,7 +703,7 @@ fn load_and_validate_projection_row( row.try_get("source_generation")?, "stored projection generation is invalid", )?; - let pubkey = RadrootsPublicKey::parse(row.try_get::<String, _>("pubkey")?.as_str()) + let pubkey = PublicKey::from_hex(row.try_get::<String, _>("pubkey")?.as_str()) .map_err(|error| projection_drift(format!("stored pubkey is invalid: {error}")))?; let event_id = RadrootsEventId::parse(row.try_get::<String, _>("event_id")?.as_str()) .map_err(|error| projection_drift(format!("stored event id is invalid: {error}")))?; @@ -714,7 +715,7 @@ fn load_and_validate_projection_row( let ingest = RadrootsEventIngest::from_raw_json(raw_json, 0) .map_err(|error| projection_drift(format!("projected event reverify failed: {error}")))?; if ingest.event().id_str() != event_id.as_str() - || ingest.event().author_str() != pubkey.as_str() + || ingest.event().author() != &pubkey || ingest.event().created_at_u64() != created_at || ingest.event().kind_u32() != 30_402 { @@ -870,7 +871,7 @@ async fn validate_fts_row( .await? .ok_or_else(|| projection_drift("FoodAvailability FTS row is missing"))?; if row.try_get::<String, _>("event_id")? != projection.event_id().as_str() - || row.try_get::<String, _>("pubkey")? != projection.pubkey().as_str() + || row.try_get::<String, _>("pubkey")? != projection.pubkey().to_hex() || row.try_get::<String, _>("d_tag")? != projection.identifier().as_str() || row.try_get::<String, _>("title")? != projection.title().as_str() || row.try_get::<String, _>("summary")? != projection.summary().as_str() diff --git a/crates/event_store/src/store/post_core_extensions_v1.rs b/crates/event_store/src/store/post_core_extensions_v1.rs @@ -78,7 +78,7 @@ async fn store_trade_mutation_event( return Ok(()); } }; - if parsed.author_pubkey.as_str() != event.author_str() { + if &parsed.author_pubkey != event.author() { storage .quarantine_trade( Some(parsed.trade_id.as_str()), diff --git a/crates/event_store/src/store/post_core_storage_v1.rs b/crates/event_store/src/store/post_core_storage_v1.rs @@ -115,10 +115,10 @@ impl<'borrow, 'db> PostCoreStorageV1<'borrow, 'db> { .bind(candidate_id) .bind(proposal_mutation_id) .bind(target_claim_mutation_id) - .bind(write.mutation.author_pubkey.as_str()) - .bind(write.mutation.counterparty_pubkey.as_str()) - .bind(write.mutation.buyer_pubkey.as_str()) - .bind(write.mutation.seller_pubkey.as_str()) + .bind(write.mutation.author_pubkey.to_hex()) + .bind(write.mutation.counterparty_pubkey.to_hex()) + .bind(write.mutation.buyer_pubkey.to_hex()) + .bind(write.mutation.seller_pubkey.to_hex()) .bind(write.mutation.farm_id.as_str()) .bind(i64_from_u64( "authored_at_unix_s", @@ -206,7 +206,7 @@ impl<'borrow, 'db> PostCoreStorageV1<'borrow, 'db> { .bind(write.mutation_id.as_str()) .bind(write.mutation.trade_id.as_str()) .bind(RadrootsTransportKind::Nostr.canonical_label()) - .bind(write.event.author_str()) + .bind(write.event.author().to_hex()) .bind(i64_from_u64("created_at", write.event.created_at_u64())?) .bind(write.stored_event_seq) .bind(write.payload_sha256) @@ -268,7 +268,7 @@ impl<'borrow, 'db> PostCoreStorageV1<'borrow, 'db> { .bind(mutation.trade_id.as_str()) .bind(reservation.candidate_id.as_str()) .bind(claim_mutation_id.as_str()) - .bind(reservation.inventory_authority_id.as_str()) + .bind(reservation.inventory_authority_id.to_hex()) .bind(i64_from_u64( "inventory_epoch", reservation.inventory_epoch, diff --git a/crates/event_store/src/store/protocol_reconciliation_v1.rs b/crates/event_store/src/store/protocol_reconciliation_v1.rs @@ -458,7 +458,7 @@ async fn insert_raw_event( "INSERT OR IGNORE INTO event_envelopes(event_id, pubkey, created_at, kind, tags_json, content, sig, raw_json, verification_status, contract_status, contract_id, event_class, projection_eligible, inserted_at_ms, updated_at_ms) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", ) .bind(event.id_str()) - .bind(event.author_str()) + .bind(event.author().to_hex()) .bind(i64_from_u64("created_at", event.created_at_u64())?) .bind(i64::from(event.kind_u32())) .bind(tags_json) @@ -632,14 +632,14 @@ async fn upsert_head( "DELETE FROM event_envelope_head WHERE coordinate_type = 'replaceable' AND kind = ? AND pubkey = ? AND d_tag IS NULL", ) .bind(i64::from(*kind)) - .bind(pubkey.as_str()) + .bind(pubkey.to_hex()) .execute(&mut **tx) .await?; sqlx::query( "INSERT INTO event_envelope_head(coordinate_type, kind, pubkey, d_tag, event_id, created_at, updated_at_ms) VALUES ('replaceable', ?, ?, NULL, ?, ?, ?)", ) .bind(i64::from(*kind)) - .bind(pubkey.as_str()) + .bind(pubkey.to_hex()) .bind(candidate.event_id.as_str()) .bind(i64_from_u64("created_at", candidate.created_at)?) .bind(updated_at_ms) @@ -655,7 +655,7 @@ async fn upsert_head( "DELETE FROM event_envelope_head WHERE coordinate_type = 'addressable' AND kind = ? AND pubkey = ? AND d_tag = ?", ) .bind(i64::from(*kind)) - .bind(pubkey.as_str()) + .bind(pubkey.to_hex()) .bind(d_tag.as_str()) .execute(&mut **tx) .await?; @@ -663,7 +663,7 @@ async fn upsert_head( "INSERT INTO event_envelope_head(coordinate_type, kind, pubkey, d_tag, event_id, created_at, updated_at_ms) VALUES ('addressable', ?, ?, ?, ?, ?, ?)", ) .bind(i64::from(*kind)) - .bind(pubkey.as_str()) + .bind(pubkey.to_hex()) .bind(d_tag.as_str()) .bind(candidate.event_id.as_str()) .bind(i64_from_u64("created_at", candidate.created_at)?) diff --git a/crates/event_store/src/store/protocol_storage_v1.rs b/crates/event_store/src/store/protocol_storage_v1.rs @@ -5,7 +5,7 @@ use crate::model::reconciliation_v1::{ }; use radroots_event::envelope::RadrootsEventKind; use radroots_event::event_head::v1::RadrootsEventHeadCoordinate; -use radroots_event::ids::RadrootsPublicKey; +use radroots_identity::PublicKey; use sqlx::sqlite::SqliteRow; use sqlx::{Row, Sqlite, Transaction}; @@ -101,7 +101,7 @@ pub(super) async fn raw_head_snapshot_in_transaction( "SELECT event.seq, event.event_id, event.pubkey, event.created_at, event.kind, event.tags_json, event.content, event.sig, event.raw_json, event.verification_status, event.contract_status, event.contract_id, event.event_class, event.projection_eligible, event.inserted_at_ms, event.updated_at_ms, head.coordinate_type AS raw_head_coordinate_type, head.kind AS raw_head_kind, head.pubkey AS raw_head_pubkey, head.d_tag AS raw_head_d_tag, head.event_id AS raw_head_event_id, head.created_at AS raw_head_created_at, head.updated_at_ms AS raw_head_updated_at_ms FROM event_envelope_head AS head LEFT JOIN event_envelopes AS event ON event.event_id = head.event_id WHERE head.coordinate_type = 'replaceable' AND head.kind = ? AND head.pubkey = ? AND head.d_tag IS NULL", ) .bind(i64::from(*kind)) - .bind(pubkey.as_str()) + .bind(pubkey.to_hex()) .fetch_optional(&mut **tx) .await? } @@ -114,7 +114,7 @@ pub(super) async fn raw_head_snapshot_in_transaction( "SELECT event.seq, event.event_id, event.pubkey, event.created_at, event.kind, event.tags_json, event.content, event.sig, event.raw_json, event.verification_status, event.contract_status, event.contract_id, event.event_class, event.projection_eligible, event.inserted_at_ms, event.updated_at_ms, head.coordinate_type AS raw_head_coordinate_type, head.kind AS raw_head_kind, head.pubkey AS raw_head_pubkey, head.d_tag AS raw_head_d_tag, head.event_id AS raw_head_event_id, head.created_at AS raw_head_created_at, head.updated_at_ms AS raw_head_updated_at_ms FROM event_envelope_head AS head LEFT JOIN event_envelopes AS event ON event.event_id = head.event_id WHERE head.coordinate_type = 'addressable' AND head.kind = ? AND head.pubkey = ? AND head.d_tag = ?", ) .bind(i64::from(*kind)) - .bind(pubkey.as_str()) + .bind(pubkey.to_hex()) .bind(d_tag.as_str()) .fetch_optional(&mut **tx) .await? @@ -140,7 +140,7 @@ pub(super) fn raw_head_coordinate_for_stored_event( let inconsistent = || RadrootsEventStoreError::StoredHeadInconsistent { event_id: event.event_id.clone(), }; - let pubkey = RadrootsPublicKey::parse(event.pubkey.clone()).map_err(|_| inconsistent())?; + let pubkey = PublicKey::from_hex(&event.pubkey).map_err(|_| inconsistent())?; match event.event_class { StoredEventClass::Replaceable => Ok(RadrootsEventHeadCoordinate::Replaceable { kind: event.kind, @@ -192,7 +192,7 @@ fn validate_raw_head_snapshot( StoredEventClass::Replaceable if raw_head.d_tag.is_none() => { RadrootsEventHeadCoordinate::Replaceable { kind: raw_head.kind, - pubkey: RadrootsPublicKey::parse(raw_head.pubkey.clone()).map_err(|_| { + pubkey: PublicKey::from_hex(&raw_head.pubkey).map_err(|_| { RadrootsEventStoreError::StoredHeadInconsistent { event_id: raw_head.event_id.clone(), } @@ -201,7 +201,7 @@ fn validate_raw_head_snapshot( } StoredEventClass::Addressable => RadrootsEventHeadCoordinate::Addressable { kind: raw_head.kind, - pubkey: RadrootsPublicKey::parse(raw_head.pubkey.clone()).map_err(|_| { + pubkey: PublicKey::from_hex(&raw_head.pubkey).map_err(|_| { RadrootsEventStoreError::StoredHeadInconsistent { event_id: raw_head.event_id.clone(), } diff --git a/crates/event_store/tests/food_availability_projection_v1_result_vector.rs b/crates/event_store/tests/food_availability_projection_v1_result_vector.rs @@ -1,7 +1,7 @@ #![forbid(unsafe_code)] use radroots_blossom::RadrootsBlossomSha256; -use radroots_event::{food_availability::RadrootsFoodIdentifier, ids::RadrootsPublicKey}; +use radroots_event::food_availability::RadrootsFoodIdentifier; use radroots_event_store::{ RADROOTS_ADDRESSABLE_TRANSITION_FEED_VERSION_V1, RADROOTS_FOOD_AVAILABILITY_PROJECTION_VERSION_V1, @@ -12,6 +12,7 @@ use radroots_event_store::{ RadrootsStoreProducedCanonicalEventV1, RadrootsStoredFoodAvailabilityV1, RadrootsStoredRawEvent, }; +use radroots_identity::PublicKey; use serde::{Deserialize, Serialize}; use sha2::{Digest, Sha256}; @@ -401,7 +402,7 @@ async fn execute_case(case: ProjectionCase) { .unwrap_or_else(|error| panic!("{}: active source generation: {error}", case.id)); assert_eq!(case.expected.coordinate.kind, 30_402, "{}", case.id); - let public_key = RadrootsPublicKey::parse(&case.expected.coordinate.pubkey) + let public_key = PublicKey::from_hex(&case.expected.coordinate.pubkey) .unwrap_or_else(|error| panic!("{}: expected public key: {error}", case.id)); let identifier = RadrootsFoodIdentifier::parse(&case.expected.coordinate.d_tag) .unwrap_or_else(|error| panic!("{}: expected identifier: {error}", case.id)); @@ -513,7 +514,7 @@ async fn execute_case(case: ProjectionCase) { case.id ); assert_eq!( - actual.coordinate().pubkey().as_str(), + actual.coordinate().pubkey().to_hex(), expected.coordinate.pubkey, "{}", case.id @@ -563,7 +564,7 @@ async fn execute_case(case: ProjectionCase) { match (expected.cause_event.0.as_ref(), actual.cause_event()) { (Some(expected), Some(actual)) => { assert_event_reference(&case.id, "cause", &expected.event, actual.event()); - assert_eq!(actual.pubkey().as_str(), expected.pubkey, "{}", case.id); + assert_eq!(actual.pubkey().to_hex(), expected.pubkey, "{}", case.id); assert_eq!(actual.created_at(), expected.created_at, "{}", case.id); assert_eq!(actual.kind(), expected.kind, "{}", case.id); assert_eq!( @@ -805,7 +806,7 @@ fn assert_canonical_visible_event( .unwrap_or_else(|| panic!("{}: expected event is absent from input", case.id)); assert_eq!(actual.event_id().as_str(), observed.event.id, "{}", case.id); assert_eq!( - actual.pubkey().as_str(), + actual.pubkey().to_hex(), observed.event.pubkey, "{}", case.id diff --git a/crates/identity/src/error.rs b/crates/identity/src/error.rs @@ -2,7 +2,7 @@ use thiserror::Error; /// Errors produced while validating public identity values. #[non_exhaustive] -#[derive(Debug, Error)] +#[derive(Clone, Debug, Error, PartialEq, Eq)] pub enum Error { #[error("identifier byte representation must contain {expected} bytes, but contained {actual}")] InvalidByteLength { expected: usize, actual: usize }, diff --git a/crates/net/src/net.rs b/crates/net/src/net.rs @@ -148,10 +148,9 @@ impl Net { pub fn selected_nostr_keys(&self) -> Option<radroots_nostr::prelude::RadrootsNostrKeys> { let signer = self.selected_nostr_signer()?; self.accounts - .resolve_signing_identity_for_signer(&signer) + .resolve_signing_keys_for_signer(&signer) .ok() .flatten() - .map(|identity| identity.into_keys()) } } @@ -172,13 +171,23 @@ impl NetHandle { mod tests { use crate::builder::NetBuilder; #[cfg(feature = "nostr-client")] - use radroots_identity::RadrootsIdentity; + use radroots_identity::{PublicIdentity, PublicKey}; + #[cfg(feature = "nostr-client")] + use radroots_nostr::prelude::RadrootsNostrKeys; #[cfg(feature = "nostr-client")] use radroots_nostr_signer::prelude::{ RadrootsNostrRemoteSessionSignerCapability, RadrootsNostrSignerCapability, RadrootsNostrSignerConnectionId, }; + #[cfg(feature = "nostr-client")] + fn public_identity() -> PublicIdentity { + let keys = RadrootsNostrKeys::generate(); + PublicIdentity::new( + PublicKey::from_hex(&keys.public_key().to_hex()).expect("public identity"), + ) + } + #[test] fn builds_minimal() { let cfg = crate::config::NetConfig::default(); @@ -217,7 +226,7 @@ mod tests { assert!(net.selected_nostr_signer().is_none()); net.accounts - .generate_identity(Some("primary".into()), true) + .generate_keys(Some("primary".into()), true) .expect("generate account"); assert!(net.selected_nostr_keys().is_some()); assert!(net.selected_nostr_signer().is_some()); @@ -225,8 +234,8 @@ mod tests { let remote = RadrootsNostrSignerCapability::RemoteSession(Box::new( RadrootsNostrRemoteSessionSignerCapability::new( RadrootsNostrSignerConnectionId::new_v7(), - RadrootsIdentity::generate().to_public(), - RadrootsIdentity::generate().to_public(), + public_identity(), + public_identity(), ), )); net.set_nostr_signer(Some(remote.clone())); diff --git a/crates/nostr/src/client.rs b/crates/nostr/src/client.rs @@ -6,7 +6,6 @@ use std::collections::HashMap; use std::net::SocketAddr; use nostr_sdk::{Client, ClientBuilder, ClientOptions}; -use radroots_identity::RadrootsIdentity; use crate::error::RadrootsNostrError; #[cfg(feature = "events")] @@ -141,14 +140,6 @@ impl RadrootsNostrClient { Self { inner } } - pub fn from_identity(identity: &RadrootsIdentity) -> Self { - Self::new(identity.keys().clone()) - } - - pub fn from_identity_owned(identity: RadrootsIdentity) -> Self { - Self::new(identity.into_keys()) - } - pub fn from_inner(inner: Client) -> Self { Self { inner } } @@ -462,6 +453,7 @@ pub async fn radroots_nostr_fetch_event_by_id( mod tests { use super::{RadrootsNostrClient, RadrootsNostrClientOptions}; use crate::error::RadrootsNostrError; + use crate::test_fixtures::FIXTURE_BOB_PUBLIC_KEY_HEX; use crate::types::{ RadrootsNostrFilter, RadrootsNostrGenericEventBuilder, RadrootsNostrKeys, RadrootsNostrKind, RadrootsNostrSecretKey, RadrootsNostrSubscriptionId, RadrootsNostrTag, @@ -603,7 +595,7 @@ mod tests { let client = RadrootsNostrClient::new(keys); let reference = radroots_event::reply::RadrootsNip10ReplyReference::parse( "a".repeat(64), - "b".repeat(64), + FIXTURE_BOB_PUBLIC_KEY_HEX, None, ) .expect("reference"); diff --git a/crates/nostr/src/draft_signing.rs b/crates/nostr/src/draft_signing.rs @@ -13,9 +13,9 @@ pub fn radroots_nostr_sign_frozen_draft( ) -> Result<RadrootsSignedEvent, RadrootsNostrError> { draft.validate_for_signing()?; let actual_pubkey = keys.public_key().to_hex(); - if actual_pubkey != draft.expected_pubkey_str() { + if actual_pubkey != draft.expected_pubkey().to_hex() { return Err(RadrootsNostrError::FrozenDraftPubkeyMismatch { - expected_pubkey: draft.expected_pubkey_str().to_owned(), + expected_pubkey: draft.expected_pubkey().to_hex().to_owned(), actual_pubkey, }); } @@ -74,7 +74,7 @@ mod tests { let signed = radroots_nostr_sign_frozen_draft(&keys, &draft).expect("signed event"); assert_eq!(signed.id_str(), draft.expected_event_id_str()); - assert_eq!(signed.pubkey_str(), draft.expected_pubkey_str()); + assert_eq!(signed.pubkey().to_hex(), draft.expected_pubkey().to_hex()); assert_eq!(signed.created_at(), draft.created_at_u64()); assert_eq!(signed.kind(), draft.kind_u32()); assert_eq!(signed.tags_as_vec(), draft.tags_as_vec()); diff --git a/crates/nostr/src/event_verify.rs b/crates/nostr/src/event_verify.rs @@ -89,7 +89,7 @@ mod tests { ) -> RadrootsEventEnvelope { RadrootsEventEnvelope::new(RadrootsEventEnvelopeParts { id: event.id_str().to_owned(), - author: event.author_str().to_owned(), + author: event.author().to_hex().to_owned(), created_at: event.created_at_u64(), kind, tags: event.tags_as_vec(), @@ -173,7 +173,7 @@ mod tests { let original = signed_event(); let kind = u32::from(u16::MAX) + 1; let id = compute_canonical_nip01_event_id( - original.author_str(), + &original.author().to_hex(), original.created_at_u64(), kind, &original.tags_as_vec(), @@ -183,7 +183,7 @@ mod tests { .into_string(); let event = RadrootsEventEnvelope::new(RadrootsEventEnvelopeParts { id, - author: original.author_str().to_owned(), + author: original.author().to_hex().to_owned(), created_at: original.created_at_u64(), kind, tags: original.tags_as_vec(), diff --git a/crates/nostr/src/events/comment.rs b/crates/nostr/src/events/comment.rs @@ -60,6 +60,7 @@ fn builder_from_wire_parts( #[cfg(test)] mod tests { use super::*; + use crate::test_fixtures::FIXTURE_BOB_PUBLIC_KEY_HEX; use radroots_event::{ comment::{RadrootsAuthoredNip22Comment, RadrootsNip22EventRootReference}, kinds::{KIND_CLASSIFIED_LISTING, KIND_COMMENT}, @@ -69,7 +70,7 @@ mod tests { fn typed_comment_builder_signs_exact_kind_and_tags() { let root = RadrootsNip22EventRootReference::parse( "a".repeat(64), - "b".repeat(64), + FIXTURE_BOB_PUBLIC_KEY_HEX, KIND_CLASSIFIED_LISTING, None, ) diff --git a/crates/nostr/src/job_adapter.rs b/crates/nostr/src/job_adapter.rs @@ -37,8 +37,8 @@ impl<'a> JobEventBorrow<'a> for RadrootsNostrEventAdapter<'a> { &self.id_hex } #[inline] - fn raw_author(&'a self) -> &'a str { - &self.author_hex + fn raw_author(&'a self) -> String { + self.author_hex.clone() } #[inline] fn raw_content(&'a self) -> &'a str { diff --git a/crates/nostr_accounts/Cargo.toml b/crates/nostr_accounts/Cargo.toml @@ -15,6 +15,7 @@ readme = "README" [features] default = ["std", "file-store", "memory-vault"] std = [ + "dep:nostr", "dep:serde", "dep:serde_json", "dep:radroots_identity", @@ -29,6 +30,7 @@ os-keyring = ["std", "radroots_secret_vault/os-keyring"] nostrdb-bridge = ["std", "dep:radroots_nostrdb"] [dependencies] +nostr = { workspace = true, optional = true } radroots_identity = { workspace = true, optional = true, default-features = false, features = [ "std", "serde", diff --git a/crates/nostr_accounts/src/error.rs b/crates/nostr_accounts/src/error.rs @@ -31,8 +31,8 @@ pub enum RadrootsNostrAccountsError { } #[cfg(feature = "std")] -impl From<radroots_identity::IdentityError> for RadrootsNostrAccountsError { - fn from(value: radroots_identity::IdentityError) -> Self { +impl From<radroots_identity::Error> for RadrootsNostrAccountsError { + fn from(value: radroots_identity::Error) -> Self { Self::Identity(value.to_string()) } } @@ -54,14 +54,14 @@ impl From<radroots_secret_vault::RadrootsSecretVaultAccessError> for RadrootsNos #[cfg(test)] mod tests { use super::*; - use radroots_identity::IdentityError; + use radroots_identity::Error as IdentityValueError; use radroots_runtime::RuntimeJsonError; use radroots_secret_vault::RadrootsSecretVaultAccessError; use std::path::PathBuf; #[test] fn converts_identity_error() { - let source = IdentityError::PublicKeyMismatch; + let source = IdentityValueError::IdentityIdMismatch; let converted: RadrootsNostrAccountsError = source.into(); assert!(converted.to_string().starts_with("identity error:")); } diff --git a/crates/nostr_accounts/src/manager.rs b/crates/nostr_accounts/src/manager.rs @@ -1,7 +1,5 @@ use crate::error::RadrootsNostrAccountsError; -use crate::model::{ - RadrootsNostrAccountRecord, RadrootsNostrAccountStatus, RadrootsNostrAccountStoreState, -}; +use crate::model::RadrootsNostrAccountStoreState; #[cfg(feature = "memory-vault")] use crate::store::RadrootsNostrMemoryAccountStore; use crate::store::{RadrootsNostrAccountStore, RadrootsNostrFileAccountStore}; @@ -10,7 +8,11 @@ use crate::vault::RadrootsNostrSecretVaultMemory; #[cfg(feature = "os-keyring")] use crate::vault::RadrootsNostrSecretVaultOsKeyring; use crate::vault::{RadrootsSecretVault, account_secret_slot}; -use radroots_identity::{RadrootsIdentity, RadrootsIdentityId, RadrootsIdentityPublic}; +use nostr::{Keys, PublicKey as NostrPublicKey, SecretKey}; +use radroots_identity::{ + AccountId, PublicIdentity, PublicKey as IdentityPublicKey, + account::{Record as AccountRecord, Status as AccountStatus}, +}; use radroots_nostr_signer::prelude::{ RadrootsNostrLocalSignerAvailability, RadrootsNostrLocalSignerCapability, RadrootsNostrSignerCapability, @@ -59,7 +61,7 @@ impl RadrootsNostrAccountsManager { let exists = state .accounts .iter() - .any(|record| record.account_id == default_account_id); + .any(|record| record.id() == default_account_id); if !exists { state.default_account_id = None; state_dirty = true; @@ -122,27 +124,21 @@ impl RadrootsNostrAccountsManager { Ok((manager, resolved)) } - pub fn list_accounts( - &self, - ) -> Result<Vec<RadrootsNostrAccountRecord>, RadrootsNostrAccountsError> { + pub fn list_accounts(&self) -> Result<Vec<AccountRecord>, RadrootsNostrAccountsError> { let guard = self.state.read().map_err(|_| { RadrootsNostrAccountsError::Store("accounts state lock poisoned".into()) })?; Ok(guard.accounts.clone()) } - pub fn default_account_id( - &self, - ) -> Result<Option<RadrootsIdentityId>, RadrootsNostrAccountsError> { + pub fn default_account_id(&self) -> Result<Option<AccountId>, RadrootsNostrAccountsError> { let guard = self.state.read().map_err(|_| { RadrootsNostrAccountsError::Store("accounts state lock poisoned".into()) })?; Ok(guard.default_account_id.clone()) } - pub fn default_account( - &self, - ) -> Result<Option<RadrootsNostrAccountRecord>, RadrootsNostrAccountsError> { + pub fn default_account(&self) -> Result<Option<AccountRecord>, RadrootsNostrAccountsError> { let guard = self.state.read().map_err(|_| { RadrootsNostrAccountsError::Store("accounts state lock poisoned".into()) })?; @@ -152,61 +148,57 @@ impl RadrootsNostrAccountsManager { Ok(guard .accounts .iter() - .find(|record| &record.account_id == default_account_id) + .find(|record| record.id() == *default_account_id) .cloned()) } pub fn default_public_identity( &self, - ) -> Result<Option<RadrootsIdentityPublic>, RadrootsNostrAccountsError> { + ) -> Result<Option<PublicIdentity>, RadrootsNostrAccountsError> { Ok(self .default_account()? - .map(|record| record.public_identity.clone())) + .map(|record| record.public_identity().clone())) } - pub fn default_account_status( - &self, - ) -> Result<RadrootsNostrAccountStatus, RadrootsNostrAccountsError> { + pub fn default_account_status(&self) -> Result<AccountStatus, RadrootsNostrAccountsError> { let Some(record) = self.default_account()? else { - return Ok(RadrootsNostrAccountStatus::NotConfigured); + return Ok(AccountStatus::NotConfigured); }; Ok(match self.local_signer_availability(&record)? { RadrootsNostrLocalSignerAvailability::PublicOnly => { - RadrootsNostrAccountStatus::PublicOnly { account: record } + AccountStatus::PublicOnly { account: record } } RadrootsNostrLocalSignerAvailability::SecretBacked => { - RadrootsNostrAccountStatus::Ready { account: record } + AccountStatus::Ready { account: record } } }) } - pub fn default_signing_identity( - &self, - ) -> Result<Option<RadrootsIdentity>, RadrootsNostrAccountsError> { + pub fn default_signing_keys(&self) -> Result<Option<Keys>, RadrootsNostrAccountsError> { let Some(record) = self.default_account()? else { return Ok(None); }; - self.resolve_signing_identity(record) + self.resolve_signing_keys(record) } - pub fn get_signing_identity( + pub fn get_signing_keys( &self, - account_id: &RadrootsIdentityId, - ) -> Result<Option<RadrootsIdentity>, RadrootsNostrAccountsError> { + account_id: &AccountId, + ) -> Result<Option<Keys>, RadrootsNostrAccountsError> { let guard = self.state.read().map_err(|_| { RadrootsNostrAccountsError::Store("accounts state lock poisoned".into()) })?; let Some(record) = guard .accounts .iter() - .find(|record| &record.account_id == account_id) + .find(|record| record.id() == *account_id) .cloned() else { return Ok(None); }; drop(guard); - self.resolve_signing_identity(record) + self.resolve_signing_keys(record) } pub fn default_signer_capability( @@ -220,7 +212,7 @@ impl RadrootsNostrAccountsManager { pub fn get_signer_capability( &self, - account_id: &RadrootsIdentityId, + account_id: &AccountId, ) -> Result<Option<RadrootsNostrSignerCapability>, RadrootsNostrAccountsError> { let guard = self.state.read().map_err(|_| { RadrootsNostrAccountsError::Store("accounts state lock poisoned".into()) @@ -228,7 +220,7 @@ impl RadrootsNostrAccountsManager { let Some(record) = guard .accounts .iter() - .find(|record| &record.account_id == account_id) + .find(|record| record.id() == *account_id) .cloned() else { return Ok(None); @@ -237,44 +229,44 @@ impl RadrootsNostrAccountsManager { Ok(Some(self.local_signer_capability(record)?)) } - pub fn resolve_signing_identity_for_signer( + pub fn resolve_signing_keys_for_signer( &self, signer: &RadrootsNostrSignerCapability, - ) -> Result<Option<RadrootsIdentity>, RadrootsNostrAccountsError> { + ) -> Result<Option<Keys>, RadrootsNostrAccountsError> { match signer { RadrootsNostrSignerCapability::LocalAccount(capability) => { - self.get_signing_identity(&capability.account_id) + self.get_signing_keys(&capability.account_id) } RadrootsNostrSignerCapability::RemoteSession(_) => Ok(None), } } - pub fn upsert_identity( + pub fn upsert_keys( &self, - identity: &RadrootsIdentity, + keys: &Keys, label: Option<String>, make_default: bool, - ) -> Result<RadrootsIdentityId, RadrootsNostrAccountsError> { - let account_id = identity.id(); - let secret_key_hex = Zeroizing::new(identity.secret_key_hex()); + ) -> Result<AccountId, RadrootsNostrAccountsError> { + let public_identity = public_identity_from_keys(keys)?; + let account_id = AccountId::from_public_identity(&public_identity); + let secret_key_hex = Zeroizing::new(keys.secret_key().to_secret_hex()); self.vault.store_secret( account_secret_slot(&account_id).as_str(), secret_key_hex.as_str(), )?; - let public_identity = identity.to_public(); self.upsert_public_identity(public_identity, label, make_default) } /// Attaches matching secret material to an existing account without import semantics. - pub fn attach_identity_secret( + pub fn attach_secret_keys( &self, - account_id: &RadrootsIdentityId, - identity: &RadrootsIdentity, + account_id: &AccountId, + keys: &Keys, make_default: bool, - ) -> Result<RadrootsNostrAccountRecord, RadrootsNostrAccountsError> { - let account_id = account_id.clone(); - let public_key_hex = identity.public_key_hex(); + ) -> Result<AccountRecord, RadrootsNostrAccountsError> { + let account_id = *account_id; + let public_key_hex = keys.public_key().to_hex(); let updated_at_unix = now_unix_secs(); let mut guard = self.state.write().map_err(|_| { RadrootsNostrAccountsError::Store("accounts state lock poisoned".into()) @@ -283,23 +275,23 @@ impl RadrootsNostrAccountsManager { let Some(record) = next .accounts .iter_mut() - .find(|record| record.account_id == account_id) + .find(|record| record.id() == account_id) else { return Err(RadrootsNostrAccountsError::AccountNotFound( account_id.to_string(), )); }; - if record.public_identity.public_key_hex.as_str() != public_key_hex.as_str() { + if record.public_identity().public_key().to_hex() != public_key_hex { return Err(RadrootsNostrAccountsError::PublicKeyMismatch); } - let secret_key_hex = Zeroizing::new(identity.secret_key_hex()); + let secret_key_hex = Zeroizing::new(keys.secret_key().to_secret_hex()); self.vault.store_secret( account_secret_slot(&account_id).as_str(), secret_key_hex.as_str(), )?; - record.touch_updated(updated_at_unix); + record.touch_updated(updated_at_unix)?; let updated_record = record.clone(); if make_default { next.default_account_id = Some(account_id); @@ -311,30 +303,30 @@ impl RadrootsNostrAccountsManager { pub fn upsert_public_identity( &self, - public_identity: RadrootsIdentityPublic, + public_identity: PublicIdentity, label: Option<String>, make_default: bool, - ) -> Result<RadrootsIdentityId, RadrootsNostrAccountsError> { + ) -> Result<AccountId, RadrootsNostrAccountsError> { let updated_at_unix = now_unix_secs(); - let account_id = public_identity.id.clone(); + let account_id = AccountId::from_public_identity(&public_identity); self.update_state(|state| { - if public_identity.id.as_str() != public_identity.public_key_hex { - return Err(RadrootsNostrAccountsError::InvalidState( - "public identity id does not match public key".into(), - )); - } if let Some(existing) = state .accounts .iter_mut() - .find(|record| record.account_id == account_id) + .find(|record| record.id() == account_id) { - existing.public_identity = public_identity.clone(); - if let Some(next_label) = label.clone() { - existing.label = Some(next_label); - } - existing.touch_updated(updated_at_unix); + let next_label = label + .clone() + .or_else(|| existing.label().map(ToOwned::to_owned)); + *existing = AccountRecord::try_from_parts( + existing.id(), + public_identity.clone(), + next_label, + existing.created_at_unix(), + updated_at_unix, + )?; } else { - state.accounts.push(RadrootsNostrAccountRecord::new( + state.accounts.push(AccountRecord::new( public_identity.clone(), label.clone(), updated_at_unix, @@ -342,32 +334,32 @@ impl RadrootsNostrAccountsManager { } if state.default_account_id.is_none() || make_default { - state.default_account_id = Some(account_id.clone()); + state.default_account_id = Some(account_id); } Ok(()) })?; Ok(account_id) } - pub fn generate_identity( + pub fn generate_keys( &self, label: Option<String>, make_default: bool, - ) -> Result<RadrootsIdentityId, RadrootsNostrAccountsError> { - let identity = RadrootsIdentity::generate(); - self.upsert_identity(&identity, label, make_default) + ) -> Result<AccountId, RadrootsNostrAccountsError> { + let keys = Keys::generate(); + self.upsert_keys(&keys, label, make_default) } pub fn set_default_account( &self, - account_id: &RadrootsIdentityId, + account_id: &AccountId, ) -> Result<(), RadrootsNostrAccountsError> { - let account_id = account_id.clone(); + let account_id = *account_id; self.update_state(|state| { let exists = state .accounts .iter() - .any(|record| record.account_id == account_id); + .any(|record| record.id() == account_id); if !exists { return Err(RadrootsNostrAccountsError::AccountNotFound( account_id.to_string(), @@ -388,7 +380,7 @@ impl RadrootsNostrAccountsManager { pub fn resolve_account_selector( &self, selector: &str, - ) -> Result<RadrootsNostrAccountRecord, RadrootsNostrAccountsError> { + ) -> Result<AccountRecord, RadrootsNostrAccountsError> { let normalized = selector.trim(); if normalized.is_empty() { return Err(RadrootsNostrAccountsError::InvalidAccountSelector( @@ -396,6 +388,7 @@ impl RadrootsNostrAccountsManager { )); } + let selector_public_key = NostrPublicKey::parse(normalized).ok(); let guard = self.state.read().map_err(|_| { RadrootsNostrAccountsError::Store("accounts state lock poisoned".into()) })?; @@ -403,8 +396,10 @@ impl RadrootsNostrAccountsManager { .accounts .iter() .find(|record| { - record.account_id.as_str() == normalized - || record.public_identity.public_key_npub == normalized + record.id().to_hex() == normalized + || selector_public_key.is_some_and(|key| { + record.public_identity().public_key().to_hex() == key.to_hex() + }) }) .cloned() { @@ -414,7 +409,7 @@ impl RadrootsNostrAccountsManager { let mut label_matches = guard .accounts .iter() - .filter(|record| record.label.as_deref() == Some(normalized)) + .filter(|record| record.label() == Some(normalized)) .cloned(); let Some(record) = label_matches.next() else { return Err(RadrootsNostrAccountsError::AccountNotFound( @@ -429,23 +424,18 @@ impl RadrootsNostrAccountsManager { Ok(record) } - pub fn remove_account( - &self, - account_id: &RadrootsIdentityId, - ) -> Result<(), RadrootsNostrAccountsError> { - let account_id = account_id.clone(); + pub fn remove_account(&self, account_id: &AccountId) -> Result<(), RadrootsNostrAccountsError> { + let account_id = *account_id; self.update_state(|state| { let before = state.accounts.len(); - state - .accounts - .retain(|record| record.account_id != account_id); + state.accounts.retain(|record| record.id() != account_id); if state.accounts.len() == before { return Err(RadrootsNostrAccountsError::AccountNotFound( account_id.to_string(), )); } - if state.default_account_id.as_ref() == Some(&account_id) { + if state.default_account_id == Some(account_id) { state.default_account_id = None; } Ok(()) @@ -457,43 +447,40 @@ impl RadrootsNostrAccountsManager { pub fn export_secret_hex( &self, - account_id: &RadrootsIdentityId, + account_id: &AccountId, ) -> Result<Option<String>, RadrootsNostrAccountsError> { self.vault .load_secret(account_secret_slot(account_id).as_str()) .map_err(Into::into) } - fn resolve_signing_identity( + fn resolve_signing_keys( &self, - record: RadrootsNostrAccountRecord, - ) -> Result<Option<RadrootsIdentity>, RadrootsNostrAccountsError> { + record: AccountRecord, + ) -> Result<Option<Keys>, RadrootsNostrAccountsError> { let Some(secret_key_hex) = self .vault - .load_secret(account_secret_slot(&record.account_id).as_str())? + .load_secret(account_secret_slot(&record.id()).as_str())? else { return Ok(None); }; let secret_key_hex = Zeroizing::new(secret_key_hex); - let mut identity = RadrootsIdentity::from_secret_key_str(secret_key_hex.as_str())?; - if identity.public_key_hex() != record.public_identity.public_key_hex { + let keys = keys_from_secret_hex(secret_key_hex.as_str())?; + if keys.public_key().to_hex() != record.public_identity().public_key().to_hex() { return Err(RadrootsNostrAccountsError::PublicKeyMismatch); } - if let Some(profile) = record.public_identity.profile { - identity.set_profile(profile); - } - Ok(Some(identity)) + Ok(Some(keys)) } fn local_signer_capability( &self, - record: RadrootsNostrAccountRecord, + record: AccountRecord, ) -> Result<RadrootsNostrSignerCapability, RadrootsNostrAccountsError> { let availability = self.local_signer_availability(&record)?; Ok(RadrootsNostrSignerCapability::LocalAccount(Box::new( RadrootsNostrLocalSignerCapability::new( - record.account_id, - record.public_identity, + record.id(), + record.public_identity().clone(), availability, ), ))) @@ -501,18 +488,18 @@ impl RadrootsNostrAccountsManager { fn local_signer_availability( &self, - record: &RadrootsNostrAccountRecord, + record: &AccountRecord, ) -> Result<RadrootsNostrLocalSignerAvailability, RadrootsNostrAccountsError> { let Some(secret_key_hex) = self .vault - .load_secret(account_secret_slot(&record.account_id).as_str())? + .load_secret(account_secret_slot(&record.id()).as_str())? else { return Ok(RadrootsNostrLocalSignerAvailability::PublicOnly); }; let secret_key_hex = Zeroizing::new(secret_key_hex); - let identity = RadrootsIdentity::from_secret_key_str(secret_key_hex.as_str())?; - if identity.public_key_hex() != record.public_identity.public_key_hex { + let keys = keys_from_secret_hex(secret_key_hex.as_str())?; + if keys.public_key().to_hex() != record.public_identity().public_key().to_hex() { return Err(RadrootsNostrAccountsError::PublicKeyMismatch); } Ok(RadrootsNostrLocalSignerAvailability::SecretBacked) @@ -535,6 +522,17 @@ impl RadrootsNostrAccountsManager { } } +fn public_identity_from_keys(keys: &Keys) -> Result<PublicIdentity, RadrootsNostrAccountsError> { + let public_key = IdentityPublicKey::from_hex(&keys.public_key().to_hex())?; + Ok(PublicIdentity::new(public_key)) +} + +fn keys_from_secret_hex(secret_key_hex: &str) -> Result<Keys, RadrootsNostrAccountsError> { + let secret_key = SecretKey::from_hex(secret_key_hex) + .map_err(|error| RadrootsNostrAccountsError::Identity(error.to_string()))?; + Ok(Keys::new(secret_key)) +} + fn local_file_backed_secret_vault( backend: RadrootsSecretBackend, secrets_dir: &Path, @@ -579,7 +577,8 @@ mod tests { }; use crate::vault::RadrootsNostrSecretVaultMemory; use crate::vault::RadrootsSecretVault; - use radroots_identity::RadrootsIdentityProfile; + use nostr::{Keys, ToBech32}; + use radroots_identity::{Profile, Username}; use radroots_secret_vault::{ RadrootsHostVaultCapabilities, RadrootsSecretBackend, RadrootsSecretBackendAvailability, RadrootsSecretBackendSelection, @@ -590,6 +589,31 @@ mod tests { use std::sync::RwLock; use std::thread; + trait TestKeysExt { + fn id(&self) -> AccountId; + fn to_public(&self) -> PublicIdentity; + fn public_key_hex(&self) -> String; + fn secret_key_hex(&self) -> String; + } + + impl TestKeysExt for Keys { + fn id(&self) -> AccountId { + AccountId::from_public_identity(&self.to_public()) + } + + fn to_public(&self) -> PublicIdentity { + public_identity_from_keys(self).expect("public identity") + } + + fn public_key_hex(&self) -> String { + self.public_key().to_hex() + } + + fn secret_key_hex(&self) -> String { + self.secret_key().to_secret_hex() + } + } + mod removed_surface_fixtures { pub const MIGRATE_LEGACY_IDENTITY_FILE: &str = "migrate_legacy_identity_file"; pub const SELECTED_ACCOUNT_ID: &str = "selected_account_id"; @@ -775,19 +799,22 @@ mod tests { .join(); } - fn status_kind(status: &RadrootsNostrAccountStatus) -> &'static str { + fn status_kind(status: &AccountStatus) -> &'static str { match status { - RadrootsNostrAccountStatus::NotConfigured => "not-configured", - RadrootsNostrAccountStatus::PublicOnly { .. } => "public-only", - RadrootsNostrAccountStatus::Ready { .. } => "ready", + AccountStatus::NotConfigured => "not-configured", + AccountStatus::PublicOnly { .. } => "public-only", + AccountStatus::Ready { .. } => "ready", + _ => "unknown", } } - fn status_account(status: &RadrootsNostrAccountStatus) -> Option<&RadrootsNostrAccountRecord> { + fn status_account(status: &AccountStatus) -> Option<&AccountRecord> { match status { - RadrootsNostrAccountStatus::NotConfigured => None, - RadrootsNostrAccountStatus::PublicOnly { account } - | RadrootsNostrAccountStatus::Ready { account } => Some(account), + AccountStatus::NotConfigured => None, + AccountStatus::PublicOnly { account } | AccountStatus::Ready { account } => { + Some(account) + } + _ => None, } } @@ -801,7 +828,7 @@ mod tests { let manager = RadrootsNostrAccountsManager::new(store.clone(), vault.clone()).expect("manager"); let created_id = manager - .generate_identity(Some("primary".into()), true) + .generate_keys(Some("primary".into()), true) .expect("create identity"); let default_account_id = manager @@ -816,12 +843,7 @@ mod tests { .expect("default2") .expect("default2 id"); assert_eq!(default_account_id_2, created_id); - assert!( - manager2 - .default_signing_identity() - .expect("signing") - .is_some() - ); + assert!(manager2.default_signing_keys().expect("signing").is_some()); } #[test] @@ -833,9 +855,9 @@ mod tests { RadrootsNostrSecretVaultMemory::new(), ) .expect("manager"); - let identity = RadrootsIdentity::generate(); + let identity = Keys::generate(); let account_id = manager - .upsert_identity(&identity, Some("primary".into()), true) + .upsert_keys(&identity, Some("primary".into()), true) .expect("upsert"); let reloaded = RadrootsNostrAccountsManager::new_file_backed_with_vault( @@ -859,7 +881,7 @@ mod tests { &path, serde_json::to_vec_pretty(&json!({ "version": 1, - "default_account_id": RadrootsIdentity::generate().id(), + "default_account_id": Keys::generate().id(), "accounts": [], })) .expect("serialize store"), @@ -884,7 +906,7 @@ mod tests { #[test] fn new_reports_save_error_when_dirty_state_requires_rewrite() { let state = RadrootsNostrAccountStoreState { - default_account_id: Some(RadrootsIdentity::generate().id()), + default_account_id: Some(Keys::generate().id()), ..Default::default() }; let store = Arc::new(SaveErrorStore::new(state)); @@ -1069,48 +1091,43 @@ mod tests { let vault = Arc::new(RadrootsNostrSecretVaultMemory::new()); let manager = RadrootsNostrAccountsManager::new(store, vault).expect("manager"); - let identity = RadrootsIdentity::generate(); + let identity = Keys::generate(); let public = identity.to_public(); manager .upsert_public_identity(public, Some("watch".into()), true) .expect("watch"); - assert!( - manager - .default_signing_identity() - .expect("signing") - .is_none() - ); + assert!(manager.default_signing_keys().expect("signing").is_none()); let status = manager .default_account_status() .expect("default account status"); assert_eq!(status_kind(&status), "public-only"); let account = status_account(&status).expect("account"); - assert_eq!(account.label.as_deref(), Some("watch")); + assert_eq!(account.label(), Some("watch")); } #[test] - fn attach_identity_secret_upgrades_existing_watch_only_account() { + fn attach_secret_keys_upgrades_existing_watch_only_account() { let manager = RadrootsNostrAccountsManager::new_in_memory(); - let identity = RadrootsIdentity::generate(); + let identity = Keys::generate(); let account_id = manager .upsert_public_identity(identity.to_public(), Some("watch".into()), false) .expect("watch"); manager.clear_default_account().expect("clear default"); let attached = manager - .attach_identity_secret(&account_id, &identity, false) + .attach_secret_keys(&account_id, &identity, false) .expect("attach secret"); - assert_eq!(attached.account_id, account_id); - assert_eq!(attached.label.as_deref(), Some("watch")); + assert_eq!(attached.id(), account_id); + assert_eq!(attached.label(), Some("watch")); assert_eq!( - attached.public_identity.public_key_hex, + attached.public_identity().public_key().to_hex(), identity.public_key_hex() ); assert_eq!(manager.list_accounts().expect("list").len(), 1); let signing_identity = manager - .get_signing_identity(&account_id) + .get_signing_keys(&account_id) .expect("signing") .expect("secret backed"); assert_eq!(signing_identity.public_key_hex(), identity.public_key_hex()); @@ -1118,18 +1135,18 @@ mod tests { } #[test] - fn attach_identity_secret_preserves_existing_default_when_not_requested() { + fn attach_secret_keys_preserves_existing_default_when_not_requested() { let manager = RadrootsNostrAccountsManager::new_in_memory(); let default_account_id = manager - .generate_identity(Some("primary".into()), true) + .generate_keys(Some("primary".into()), true) .expect("primary"); - let identity = RadrootsIdentity::generate(); + let identity = Keys::generate(); let account_id = manager .upsert_public_identity(identity.to_public(), Some("watch".into()), false) .expect("watch"); manager - .attach_identity_secret(&account_id, &identity, false) + .attach_secret_keys(&account_id, &identity, false) .expect("attach secret"); assert_eq!( @@ -1139,18 +1156,18 @@ mod tests { } #[test] - fn attach_identity_secret_can_explicitly_make_default() { + fn attach_secret_keys_can_explicitly_make_default() { let manager = RadrootsNostrAccountsManager::new_in_memory(); manager - .generate_identity(Some("primary".into()), true) + .generate_keys(Some("primary".into()), true) .expect("primary"); - let identity = RadrootsIdentity::generate(); + let identity = Keys::generate(); let account_id = manager .upsert_public_identity(identity.to_public(), Some("watch".into()), false) .expect("watch"); manager - .attach_identity_secret(&account_id, &identity, true) + .attach_secret_keys(&account_id, &identity, true) .expect("attach secret"); assert_eq!( @@ -1160,13 +1177,13 @@ mod tests { } #[test] - fn attach_identity_secret_rejects_missing_account_without_storing_secret() { + fn attach_secret_keys_rejects_missing_account_without_storing_secret() { let manager = RadrootsNostrAccountsManager::new_in_memory(); - let identity = RadrootsIdentity::generate(); + let identity = Keys::generate(); let missing_id = identity.id(); let err = manager - .attach_identity_secret(&missing_id, &identity, false) + .attach_secret_keys(&missing_id, &identity, false) .expect_err("missing account"); assert_eq!(err.to_string(), format!("account not found: {missing_id}")); @@ -1180,17 +1197,17 @@ mod tests { } #[test] - fn attach_identity_secret_rejects_public_key_mismatch_without_storing_secret() { + fn attach_secret_keys_rejects_public_key_mismatch_without_storing_secret() { let manager = RadrootsNostrAccountsManager::new_in_memory(); - let public_identity = RadrootsIdentity::generate(); + let public_identity = Keys::generate(); let account_id = manager .upsert_public_identity(public_identity.to_public(), Some("watch".into()), false) .expect("watch"); manager.clear_default_account().expect("clear default"); - let mismatched_identity = RadrootsIdentity::generate(); + let mismatched_identity = Keys::generate(); let err = manager - .attach_identity_secret(&account_id, &mismatched_identity, false) + .attach_secret_keys(&account_id, &mismatched_identity, false) .expect_err("public key mismatch"); assert_eq!(err.to_string(), "public key does not match secret key"); @@ -1202,7 +1219,7 @@ mod tests { ); assert!( manager - .get_signing_identity(&account_id) + .get_signing_keys(&account_id) .expect("signing") .is_none() ); @@ -1210,35 +1227,33 @@ mod tests { } #[test] - fn attach_identity_secret_reports_vault_store_error() { + fn attach_secret_keys_reports_vault_store_error() { let manager = RadrootsNostrAccountsManager::new( Arc::new(RadrootsNostrMemoryAccountStore::new()), Arc::new(VaultStoreError), ) .expect("manager"); - let identity = RadrootsIdentity::generate(); + let identity = Keys::generate(); let account_id = manager .upsert_public_identity(identity.to_public(), Some("watch".into()), false) .expect("watch"); let err = manager - .attach_identity_secret(&account_id, &identity, false) + .attach_secret_keys(&account_id, &identity, false) .expect_err("vault store error"); assert!(err.to_string().starts_with("vault error:")); } #[test] - fn attach_identity_secret_reports_store_save_error_after_secret_store() { - let identity = RadrootsIdentity::generate(); + fn attach_secret_keys_reports_store_save_error_after_secret_store() { + let identity = Keys::generate(); let public_identity = identity.to_public(); - let account_id = public_identity.id.clone(); + let account_id = AccountId::from_public_identity(&public_identity); let mut state = RadrootsNostrAccountStoreState::default(); - state.accounts.push(RadrootsNostrAccountRecord::new( - public_identity, - Some("watch".into()), - 1, - )); + state + .accounts + .push(AccountRecord::new(public_identity, Some("watch".into()), 1)); let manager = RadrootsNostrAccountsManager::new( Arc::new(SaveErrorStore::new(state)), Arc::new(RadrootsNostrSecretVaultMemory::new()), @@ -1246,7 +1261,7 @@ mod tests { .expect("manager"); let err = manager - .attach_identity_secret(&account_id, &identity, false) + .attach_secret_keys(&account_id, &identity, false) .expect_err("store save error"); assert_eq!(err.to_string(), "store error: store save failed"); @@ -1256,7 +1271,7 @@ mod tests { fn default_account_status_reports_ready_for_signing_identity() { let manager = RadrootsNostrAccountsManager::new_in_memory(); let default_account_id = manager - .generate_identity(Some("primary".into()), true) + .generate_keys(Some("primary".into()), true) .expect("generate"); let status = manager @@ -1264,8 +1279,8 @@ mod tests { .expect("default account status"); assert_eq!(status_kind(&status), "ready"); let account = status_account(&status).expect("account"); - assert_eq!(account.account_id, default_account_id); - assert_eq!(account.label.as_deref(), Some("primary")); + assert_eq!(account.id(), default_account_id); + assert_eq!(account.label(), Some("primary")); let signer = manager .default_signer_capability() @@ -1302,7 +1317,7 @@ mod tests { fn upsert_public_identity_without_label_preserves_existing_label() { let manager = RadrootsNostrAccountsManager::new_in_memory(); let account_id = manager - .generate_identity(Some("primary".into()), true) + .generate_keys(Some("primary".into()), true) .expect("generate"); let existing = manager @@ -1316,9 +1331,9 @@ mod tests { let records = manager.list_accounts().expect("list"); let record = records .into_iter() - .find(|record| record.account_id == account_id) + .find(|record| record.id() == account_id) .expect("account"); - assert_eq!(record.label.as_deref(), Some("primary")); + assert_eq!(record.label(), Some("primary")); } #[test] @@ -1343,7 +1358,7 @@ mod tests { let store = Arc::new(RadrootsNostrMemoryAccountStore::new()); let vault = Arc::new(RadrootsNostrSecretVaultMemory::new()); let state = RadrootsNostrAccountStoreState { - default_account_id: Some(RadrootsIdentity::generate().id()), + default_account_id: Some(Keys::generate().id()), ..Default::default() }; store.save(&state).expect("save"); @@ -1369,7 +1384,7 @@ mod tests { ); assert!( manager - .default_signing_identity() + .default_signing_keys() .expect("default signing") .is_none() ); @@ -1385,10 +1400,10 @@ mod tests { assert_eq!(status_kind(&status), "not-configured"); assert!(status_account(&status).is_none()); - let missing_id = RadrootsIdentity::generate().id(); + let missing_id = Keys::generate().id(); assert!( manager - .get_signing_identity(&missing_id) + .get_signing_keys(&missing_id) .expect("signing") .is_none() ); @@ -1404,7 +1419,7 @@ mod tests { fn default_account_status_propagates_secret_integrity_errors() { let manager = RadrootsNostrAccountsManager::new_in_memory(); let account_id = manager - .generate_identity(Some("primary".into()), true) + .generate_keys(Some("primary".into()), true) .expect("generate"); manager .vault @@ -1416,9 +1431,9 @@ mod tests { .expect("default account status"); assert_eq!(status_kind(&status), "public-only"); let account = status_account(&status).expect("account"); - assert_eq!(account.account_id, account_id); + assert_eq!(account.id(), account_id); - let wrong_identity = RadrootsIdentity::generate(); + let wrong_identity = Keys::generate(); manager .vault .store_secret( @@ -1443,15 +1458,14 @@ mod tests { assert!(default_err.to_string().starts_with("store error:")); let mut load_error_state = RadrootsNostrAccountStoreState::default(); - let load_error_public = RadrootsIdentity::generate().to_public(); - load_error_state - .accounts - .push(RadrootsNostrAccountRecord::new( - load_error_public.clone(), - Some("watch".into()), - 1, - )); - load_error_state.default_account_id = Some(load_error_public.id.clone()); + let load_error_public = Keys::generate().to_public(); + load_error_state.accounts.push(AccountRecord::new( + load_error_public.clone(), + Some("watch".into()), + 1, + )); + load_error_state.default_account_id = + Some(AccountId::from_public_identity(&load_error_public)); let load_error_store = Arc::new(RadrootsNostrMemoryAccountStore::new()); load_error_store .save(&load_error_state) @@ -1465,15 +1479,14 @@ mod tests { assert!(vault_load_error.to_string().starts_with("vault error:")); let mut invalid_secret_state = RadrootsNostrAccountStoreState::default(); - let invalid_secret_public = RadrootsIdentity::generate().to_public(); - invalid_secret_state - .accounts - .push(RadrootsNostrAccountRecord::new( - invalid_secret_public.clone(), - Some("invalid".into()), - 1, - )); - invalid_secret_state.default_account_id = Some(invalid_secret_public.id.clone()); + let invalid_secret_public = Keys::generate().to_public(); + invalid_secret_state.accounts.push(AccountRecord::new( + invalid_secret_public.clone(), + Some("invalid".into()), + 1, + )); + invalid_secret_state.default_account_id = + Some(AccountId::from_public_identity(&invalid_secret_public)); let invalid_secret_store = Arc::new(RadrootsNostrMemoryAccountStore::new()); invalid_secret_store .save(&invalid_secret_state) @@ -1490,15 +1503,14 @@ mod tests { #[test] fn signer_capability_paths_propagate_secret_parse_errors() { let mut invalid_secret_state = RadrootsNostrAccountStoreState::default(); - let invalid_secret_public = RadrootsIdentity::generate().to_public(); - invalid_secret_state - .accounts - .push(RadrootsNostrAccountRecord::new( - invalid_secret_public.clone(), - Some("invalid".into()), - 1, - )); - invalid_secret_state.default_account_id = Some(invalid_secret_public.id.clone()); + let invalid_secret_public = Keys::generate().to_public(); + invalid_secret_state.accounts.push(AccountRecord::new( + invalid_secret_public.clone(), + Some("invalid".into()), + 1, + )); + invalid_secret_state.default_account_id = + Some(AccountId::from_public_identity(&invalid_secret_public)); let invalid_secret_store = Arc::new(RadrootsNostrMemoryAccountStore::new()); invalid_secret_store .save(&invalid_secret_state) @@ -1517,7 +1529,7 @@ mod tests { ); let signer_error = invalid_secret_manager - .get_signer_capability(&invalid_secret_public.id) + .get_signer_capability(&AccountId::from_public_identity(&invalid_secret_public)) .expect_err("signer invalid secret"); assert!(signer_error.to_string().starts_with("identity error:")); } @@ -1526,10 +1538,10 @@ mod tests { fn select_remove_export_and_lookup_paths() { let manager = RadrootsNostrAccountsManager::new_in_memory(); let first_id = manager - .generate_identity(Some("first".into()), true) + .generate_keys(Some("first".into()), true) .expect("first"); let second_id = manager - .generate_identity(Some("second".into()), false) + .generate_keys(Some("second".into()), false) .expect("second"); manager @@ -1547,7 +1559,7 @@ mod tests { ); assert!( manager - .get_signing_identity(&second_id) + .get_signing_keys(&second_id) .expect("signing") .is_some() ); @@ -1562,7 +1574,7 @@ mod tests { ); assert!( manager - .get_signing_identity(&first_id) + .get_signing_keys(&first_id) .expect("first signing") .is_some() ); @@ -1585,7 +1597,7 @@ mod tests { fn upsert_public_identity_updates_label_and_respects_default_flag() { let manager = RadrootsNostrAccountsManager::new_in_memory(); let original_default = manager - .generate_identity(Some("primary".into()), true) + .generate_keys(Some("primary".into()), true) .expect("generate"); let existing = manager @@ -1600,12 +1612,12 @@ mod tests { .list_accounts() .expect("list") .into_iter() - .find(|record| record.account_id == existing.id) + .find(|record| record.id() == AccountId::from_public_identity(&existing)) .expect("record"); - assert_eq!(renamed.label.as_deref(), Some("renamed")); + assert_eq!(renamed.label(), Some("renamed")); - let watch_only = RadrootsIdentity::generate().to_public(); - let watch_id = watch_only.id.clone(); + let watch_only = Keys::generate().to_public(); + let watch_id = AccountId::from_public_identity(&watch_only); manager .upsert_public_identity(watch_only.clone(), Some("watch".into()), false) .expect("upsert watch"); @@ -1624,26 +1636,13 @@ mod tests { } #[test] - fn upsert_public_identity_rejects_mismatched_id() { - let manager = RadrootsNostrAccountsManager::new_in_memory(); - let mut public_identity = RadrootsIdentity::generate().to_public(); - let other = RadrootsIdentity::generate().to_public(); - public_identity.id = other.id.clone(); - - let err = manager - .upsert_public_identity(public_identity, None, true) - .expect_err("id mismatch"); - assert!(err.to_string().starts_with("invalid account state:")); - } - - #[test] fn remove_non_default_account_keeps_current_default() { let manager = RadrootsNostrAccountsManager::new_in_memory(); let default_account_id = manager - .generate_identity(Some("selected".into()), true) + .generate_keys(Some("selected".into()), true) .expect("default"); let removable_id = manager - .generate_identity(Some("removable".into()), false) + .generate_keys(Some("removable".into()), false) .expect("removable"); manager.remove_account(&removable_id).expect("remove"); @@ -1657,10 +1656,10 @@ mod tests { fn clear_default_account_clears_default_without_removing_accounts() { let manager = RadrootsNostrAccountsManager::new_in_memory(); manager - .generate_identity(Some("primary".into()), true) + .generate_keys(Some("primary".into()), true) .expect("primary"); manager - .generate_identity(Some("secondary".into()), false) + .generate_keys(Some("secondary".into()), false) .expect("secondary"); manager.clear_default_account().expect("clear default"); @@ -1673,38 +1672,42 @@ mod tests { fn resolve_account_selector_matches_exact_id_npub_and_unique_label() { let manager = RadrootsNostrAccountsManager::new_in_memory(); let account_id = manager - .generate_identity(Some("primary".into()), true) + .generate_keys(Some("primary".into()), true) .expect("primary"); let default_account = manager .default_account() .expect("default account") .expect("default record"); - let npub = default_account.public_identity.public_key_npub.clone(); + let npub = + NostrPublicKey::from_hex(&default_account.public_identity().public_key().to_hex()) + .expect("Nostr public key") + .to_bech32() + .expect("npub"); let resolved_by_id = manager - .resolve_account_selector(account_id.as_str()) + .resolve_account_selector(&account_id.to_hex()) .expect("resolve by id"); - assert_eq!(resolved_by_id.account_id, account_id); + assert_eq!(resolved_by_id.id(), account_id); let resolved_by_npub = manager .resolve_account_selector(&npub) .expect("resolve by npub"); - assert_eq!(resolved_by_npub.account_id, account_id); + assert_eq!(resolved_by_npub.id(), account_id); let resolved_by_label = manager .resolve_account_selector("primary") .expect("resolve by label"); - assert_eq!(resolved_by_label.account_id, account_id); + assert_eq!(resolved_by_label.id(), account_id); } #[test] fn resolve_account_selector_rejects_empty_and_ambiguous_labels() { let manager = RadrootsNostrAccountsManager::new_in_memory(); manager - .generate_identity(Some("shared".into()), true) + .generate_keys(Some("shared".into()), true) .expect("first"); manager - .generate_identity(Some("shared".into()), false) + .generate_keys(Some("shared".into()), false) .expect("second"); let empty = manager @@ -1732,8 +1735,8 @@ mod tests { let store = Arc::new(RadrootsNostrMemoryAccountStore::new()); let vault = Arc::new(VaultRemoveError); let manager = RadrootsNostrAccountsManager::new(store, vault.clone()).expect("manager"); - let public = RadrootsIdentity::generate().to_public(); - let account_id = public.id.clone(); + let public = Keys::generate().to_public(); + let account_id = AccountId::from_public_identity(&public); vault .store_secret(account_secret_slot(&account_id).as_str(), "secret") .expect("vault store"); @@ -1754,18 +1757,18 @@ mod tests { } #[test] - fn resolve_signing_identity_mismatch_and_profile_paths() { + fn resolve_signing_keys_mismatch_and_public_profile_paths() { let store = Arc::new(RadrootsNostrMemoryAccountStore::new()); let vault = Arc::new(RadrootsNostrSecretVaultMemory::new()); let manager = RadrootsNostrAccountsManager::new(store, vault.clone()).expect("manager"); - let mismatch_public = RadrootsIdentity::generate().to_public(); - let mismatch_id = mismatch_public.id.clone(); + let mismatch_public = Keys::generate().to_public(); + let mismatch_id = AccountId::from_public_identity(&mismatch_public); manager .upsert_public_identity(mismatch_public, Some("mismatch".into()), true) .expect("upsert mismatch"); - let wrong_identity = RadrootsIdentity::generate(); + let wrong_identity = Keys::generate(); vault .store_secret( account_secret_slot(&mismatch_id).as_str(), @@ -1774,7 +1777,7 @@ mod tests { .expect("vault store"); let mismatch = manager - .default_signing_identity() + .default_signing_keys() .expect_err("public key mismatch"); assert!( mismatch @@ -1782,24 +1785,30 @@ mod tests { .contains("public key does not match secret key") ); - let mut with_profile = RadrootsIdentity::generate(); - let profile = RadrootsIdentityProfile { - identifier: Some("profile-id".to_string()), - ..RadrootsIdentityProfile::default() - }; - with_profile.set_profile(profile); + let with_profile = Keys::generate(); + let profiled_identity = with_profile.to_public().with_profile( + Profile::new().with_username(Username::parse("profile-id").expect("username")), + ); let profile_id = manager - .upsert_identity(&with_profile, Some("profile".into()), true) + .upsert_public_identity(profiled_identity, Some("profile".into()), true) .expect("upsert profile"); + manager + .attach_secret_keys(&profile_id, &with_profile, true) + .expect("attach profile keys"); let resolved = manager - .get_signing_identity(&profile_id) + .get_signing_keys(&profile_id) .expect("resolve") .expect("identity"); + assert_eq!(resolved.public_key(), with_profile.public_key()); + let stored_profile = manager + .default_public_identity() + .expect("default public identity") + .expect("public identity"); assert_eq!( - resolved + stored_profile .profile() - .and_then(|value| value.identifier.clone()) - .as_deref(), + .and_then(Profile::username) + .map(Username::as_str), Some("profile-id") ); @@ -1809,7 +1818,7 @@ mod tests { .expect("local signer"); assert!( manager - .resolve_signing_identity_for_signer(&local_signer) + .resolve_signing_keys_for_signer(&local_signer) .expect("resolve local signer") .is_some() ); @@ -1817,13 +1826,13 @@ mod tests { let remote_signer = RadrootsNostrSignerCapability::RemoteSession(Box::new( radroots_nostr_signer::prelude::RadrootsNostrRemoteSessionSignerCapability::new( radroots_nostr_signer::prelude::RadrootsNostrSignerConnectionId::new_v7(), - RadrootsIdentity::generate().to_public(), - RadrootsIdentity::generate().to_public(), + Keys::generate().to_public(), + Keys::generate().to_public(), ), )); assert!( manager - .resolve_signing_identity_for_signer(&remote_signer) + .resolve_signing_keys_for_signer(&remote_signer) .expect("resolve remote signer") .is_none() ); @@ -1849,7 +1858,7 @@ mod tests { ) .expect("manager"); let save_error = save_error_manager - .upsert_public_identity(RadrootsIdentity::generate().to_public(), None, true) + .upsert_public_identity(Keys::generate().to_public(), None, true) .expect_err("save error"); assert!(save_error.to_string().starts_with("store error:")); @@ -1858,22 +1867,21 @@ mod tests { Arc::new(VaultStoreError), ) .expect("manager"); - let identity = RadrootsIdentity::generate(); + let identity = Keys::generate(); let vault_store_error = vault_store_error_manager - .upsert_identity(&identity, None, true) + .upsert_keys(&identity, None, true) .expect_err("vault store error"); assert!(vault_store_error.to_string().starts_with("vault error:")); let mut load_error_state = RadrootsNostrAccountStoreState::default(); - let load_error_public = RadrootsIdentity::generate().to_public(); - load_error_state - .accounts - .push(RadrootsNostrAccountRecord::new( - load_error_public.clone(), - Some("watch".into()), - 1, - )); - load_error_state.default_account_id = Some(load_error_public.id.clone()); + let load_error_public = Keys::generate().to_public(); + load_error_state.accounts.push(AccountRecord::new( + load_error_public.clone(), + Some("watch".into()), + 1, + )); + load_error_state.default_account_id = + Some(AccountId::from_public_identity(&load_error_public)); let load_error_store = Arc::new(RadrootsNostrMemoryAccountStore::new()); load_error_store .save(&load_error_state) @@ -1882,20 +1890,19 @@ mod tests { RadrootsNostrAccountsManager::new(load_error_store, Arc::new(VaultLoadError)) .expect("manager"); let vault_load_error = vault_load_error_manager - .default_signing_identity() + .default_signing_keys() .expect_err("vault load error"); assert!(vault_load_error.to_string().starts_with("vault error:")); let mut invalid_secret_state = RadrootsNostrAccountStoreState::default(); - let invalid_secret_public = RadrootsIdentity::generate().to_public(); - invalid_secret_state - .accounts - .push(RadrootsNostrAccountRecord::new( - invalid_secret_public.clone(), - Some("invalid".into()), - 1, - )); - invalid_secret_state.default_account_id = Some(invalid_secret_public.id.clone()); + let invalid_secret_public = Keys::generate().to_public(); + invalid_secret_state.accounts.push(AccountRecord::new( + invalid_secret_public.clone(), + Some("invalid".into()), + 1, + )); + invalid_secret_state.default_account_id = + Some(AccountId::from_public_identity(&invalid_secret_public)); let invalid_secret_store = Arc::new(RadrootsNostrMemoryAccountStore::new()); invalid_secret_store .save(&invalid_secret_state) @@ -1904,7 +1911,7 @@ mod tests { RadrootsNostrAccountsManager::new(invalid_secret_store, Arc::new(VaultInvalidSecret)) .expect("manager"); let invalid_secret = invalid_secret_manager - .default_signing_identity() + .default_signing_keys() .expect_err("invalid secret"); assert!(invalid_secret.to_string().starts_with("identity error:")); } @@ -1927,7 +1934,7 @@ mod tests { .expect_err("default public poisoned"); assert!(default_public_err.to_string().starts_with("store error:")); let default_signing_err = manager - .default_signing_identity() + .default_signing_keys() .expect_err("default signing poisoned"); assert!(default_signing_err.to_string().starts_with("store error:")); let default_signer_err = manager @@ -1935,14 +1942,14 @@ mod tests { .expect_err("default signer poisoned"); assert!(default_signer_err.to_string().starts_with("store error:")); - let account_id = RadrootsIdentity::generate().id(); + let account_id = Keys::generate().id(); let signing_err = manager - .get_signing_identity(&account_id) + .get_signing_keys(&account_id) .expect_err("signing poisoned"); assert!(signing_err.to_string().starts_with("store error:")); - let attach_identity = RadrootsIdentity::generate(); + let attach_identity = Keys::generate(); let attach_err = manager - .attach_identity_secret(&account_id, &attach_identity, false) + .attach_secret_keys(&account_id, &attach_identity, false) .expect_err("attach poisoned"); assert!(attach_err.to_string().starts_with("store error:")); let signer_err = manager @@ -1966,7 +1973,7 @@ mod tests { .expect_err("remove poisoned"); assert!(remove_err.to_string().starts_with("store error:")); let upsert_err = manager - .upsert_public_identity(RadrootsIdentity::generate().to_public(), None, false) + .upsert_public_identity(Keys::generate().to_public(), None, false) .expect_err("upsert poisoned"); assert!(upsert_err.to_string().starts_with("store error:")); } @@ -1991,7 +1998,7 @@ mod tests { let poisoned_load = save_error_store.load().expect_err("poisoned load"); assert!(poisoned_load.to_string().starts_with("store error:")); - let account_id = RadrootsIdentity::generate().id(); + let account_id = Keys::generate().id(); let vault_store_error = VaultStoreError; assert!( vault_store_error diff --git a/crates/nostr_accounts/src/nostrdb_bridge.rs b/crates/nostr_accounts/src/nostrdb_bridge.rs @@ -9,10 +9,10 @@ pub fn radroots_nostr_accounts_register_default_secret_with_nostrdb( let Some(signer) = manager.default_signer_capability()? else { return Ok(false); }; - let Some(identity) = manager.resolve_signing_identity_for_signer(&signer)? else { + let Some(keys) = manager.resolve_signing_keys_for_signer(&signer)? else { return Ok(false); }; - Ok(nostrdb.add_giftwrap_secret_key(identity.secret_key_bytes())) + Ok(nostrdb.add_giftwrap_secret_key(keys.secret_key().to_secret_bytes())) } #[cfg(test)] @@ -20,6 +20,8 @@ mod tests { use super::*; use crate::store::RadrootsNostrFileAccountStore; use crate::vault::RadrootsNostrSecretVaultMemory; + use nostr::Keys; + use radroots_identity::{PublicIdentity, PublicKey}; use radroots_nostrdb::prelude::RadrootsNostrdbConfig; use std::sync::Arc; @@ -32,7 +34,7 @@ mod tests { let vault = Arc::new(RadrootsNostrSecretVaultMemory::new()); let manager = RadrootsNostrAccountsManager::new(store, vault).expect("manager"); manager - .generate_identity(Some("primary".into()), true) + .generate_keys(Some("primary".into()), true) .expect("generate"); let nostrdb = @@ -52,12 +54,12 @@ mod tests { )); let vault = Arc::new(RadrootsNostrSecretVaultMemory::new()); let manager = RadrootsNostrAccountsManager::new(store, vault).expect("manager"); + let keys = Keys::generate(); + let public_identity = PublicIdentity::new( + PublicKey::from_hex(&keys.public_key().to_hex()).expect("public identity"), + ); manager - .upsert_public_identity( - radroots_identity::RadrootsIdentity::generate().to_public(), - Some("watch".into()), - true, - ) + .upsert_public_identity(public_identity, Some("watch".into()), true) .expect("watch"); let nostrdb = diff --git a/crates/nostr_accounts/src/vault.rs b/crates/nostr_accounts/src/vault.rs @@ -1,4 +1,4 @@ -use radroots_identity::RadrootsIdentityId; +use radroots_identity::AccountId; #[cfg(feature = "memory-vault")] pub use radroots_secret_vault::RadrootsSecretVaultMemory as RadrootsNostrSecretVaultMemory; @@ -7,6 +7,6 @@ pub use radroots_secret_vault::RadrootsSecretVaultOsKeyring as RadrootsNostrSecr pub use radroots_secret_vault::{RadrootsSecretVault, RadrootsSecretVaultAccessError}; #[must_use] -pub fn account_secret_slot(account_id: &RadrootsIdentityId) -> String { +pub fn account_secret_slot(account_id: &AccountId) -> String { account_id.to_string() } diff --git a/crates/nostr_signer/Cargo.toml b/crates/nostr_signer/Cargo.toml @@ -20,6 +20,7 @@ native = ["dep:radroots_sql_core", "radroots_sql_core/native"] hex = { workspace = true } nostr = { workspace = true } radroots_identity = { workspace = true, default-features = false, features = [ + "serde", "std", ] } radroots_nostr = { workspace = true, features = ["std"] } diff --git a/crates/nostr_signer/src/backend.rs b/crates/nostr_signer/src/backend.rs @@ -15,8 +15,8 @@ use crate::model::{ RadrootsNostrSignerPublishWorkflowRecord, RadrootsNostrSignerRequestAuditRecord, RadrootsNostrSignerRequestDecision, RadrootsNostrSignerWorkflowId, }; -use nostr::{Event, PublicKey, RelayUrl, UnsignedEvent}; -use radroots_identity::{RadrootsIdentity, RadrootsIdentityPublic}; +use nostr::{Event, Keys, PublicKey, RelayUrl, UnsignedEvent}; +use radroots_identity::{AccountId, PublicIdentity, PublicKey as IdentityPublicKey}; use radroots_nostr_connect::prelude::{ RadrootsNostrConnectMethod, RadrootsNostrConnectPermissions, RadrootsNostrConnectRequest, RadrootsNostrConnectRequestMessage, @@ -54,11 +54,11 @@ pub enum RadrootsNostrSignerPublishTransition { } pub trait RadrootsNostrSignerBackend: Send + Sync { - fn signer_identity(&self) -> Result<Option<RadrootsIdentityPublic>, RadrootsNostrSignerError>; + fn signer_identity(&self) -> Result<Option<PublicIdentity>, RadrootsNostrSignerError>; fn set_signer_identity( &self, - signer_identity: RadrootsIdentityPublic, + signer_identity: PublicIdentity, ) -> Result<(), RadrootsNostrSignerError>; fn capabilities( @@ -232,7 +232,8 @@ pub trait RadrootsNostrSignerBackend: Send + Sync { #[derive(Clone)] pub struct RadrootsNostrEmbeddedSignerBackend { manager: RadrootsNostrSignerManager, - signer_identity: RadrootsIdentity, + signer_keys: Keys, + signer_identity: PublicIdentity, } impl RadrootsNostrSignerBackendCapabilities { @@ -313,44 +314,43 @@ impl RadrootsNostrSignerPublishTransition { impl RadrootsNostrEmbeddedSignerBackend { pub fn new( manager: RadrootsNostrSignerManager, - signer_identity: RadrootsIdentity, + signer_keys: Keys, ) -> Result<Self, RadrootsNostrSignerError> { - let public_identity = signer_identity.to_public(); + let signer_identity = public_identity_from_keys(&signer_keys)?; let existing_identity = manager.signer_identity()?; if let Some(existing_identity) = existing_identity { - if !same_public_identity_key(&existing_identity, &public_identity) { + if !same_public_identity_key(&existing_identity, &signer_identity) { return Err(RadrootsNostrSignerError::InvalidState( "embedded signer identity does not match signer manager identity".into(), )); } } else { - manager.set_signer_identity(public_identity)?; + manager.set_signer_identity(signer_identity.clone())?; } Ok(Self { manager, + signer_keys, signer_identity, }) } - pub fn new_in_memory( - signer_identity: RadrootsIdentity, - ) -> Result<Self, RadrootsNostrSignerError> { - Self::new(RadrootsNostrSignerManager::new_in_memory(), signer_identity) + pub fn new_in_memory(signer_keys: Keys) -> Result<Self, RadrootsNostrSignerError> { + Self::new(RadrootsNostrSignerManager::new_in_memory(), signer_keys) } pub fn manager(&self) -> &RadrootsNostrSignerManager { &self.manager } - pub fn local_identity(&self) -> &RadrootsIdentity { - &self.signer_identity + pub fn local_keys(&self) -> &Keys { + &self.signer_keys } fn local_signer_capability(&self) -> RadrootsNostrLocalSignerCapability { - let public_identity = self.signer_identity.to_public(); + let public_identity = self.signer_identity.clone(); RadrootsNostrLocalSignerCapability::new( - public_identity.id.clone(), + AccountId::from_public_identity(&public_identity), public_identity, RadrootsNostrLocalSignerAvailability::SecretBacked, ) @@ -358,13 +358,13 @@ impl RadrootsNostrEmbeddedSignerBackend { } impl RadrootsNostrSignerBackend for RadrootsNostrEmbeddedSignerBackend { - fn signer_identity(&self) -> Result<Option<RadrootsIdentityPublic>, RadrootsNostrSignerError> { + fn signer_identity(&self) -> Result<Option<PublicIdentity>, RadrootsNostrSignerError> { self.manager.signer_identity() } fn set_signer_identity( &self, - signer_identity: RadrootsIdentityPublic, + signer_identity: PublicIdentity, ) -> Result<(), RadrootsNostrSignerError> { self.manager.set_signer_identity(signer_identity) } @@ -622,7 +622,7 @@ impl RadrootsNostrSignerBackend for RadrootsNostrEmbeddedSignerBackend { &self, unsigned_event: UnsignedEvent, ) -> Result<RadrootsNostrSignerSignOutput, RadrootsNostrSignerError> { - let event = unsigned_event.sign_with_keys(self.signer_identity.keys())?; + let event = unsigned_event.sign_with_keys(&self.signer_keys)?; Ok(RadrootsNostrSignerSignOutput::new( RadrootsNostrSignerCapability::LocalAccount(Box::new(self.local_signer_capability())), event, @@ -630,10 +630,17 @@ impl RadrootsNostrSignerBackend for RadrootsNostrEmbeddedSignerBackend { } } -fn same_public_identity_key(left: &RadrootsIdentityPublic, right: &RadrootsIdentityPublic) -> bool { - left.id == right.id - && left.public_key_hex == right.public_key_hex - && left.public_key_npub == right.public_key_npub +fn same_public_identity_key(left: &PublicIdentity, right: &PublicIdentity) -> bool { + left.id() == right.id() && left.public_key() == right.public_key() +} + +fn public_identity_from_keys(keys: &Keys) -> Result<PublicIdentity, RadrootsNostrSignerError> { + let public_key = IdentityPublicKey::from_hex(&keys.public_key().to_hex()).map_err(|error| { + RadrootsNostrSignerError::InvalidState(format!( + "embedded signer public key is invalid: {error}" + )) + })?; + Ok(PublicIdentity::new(public_key)) } #[cfg(test)] @@ -658,11 +665,11 @@ mod tests { }; use crate::store::RadrootsNostrSignerStore; use crate::test_support::{ - fixture_bob_identity, primary_relay, secondary_relay, synthetic_public_identity, - synthetic_public_key, synthetic_secret_hex, + fixture_bob_identity, primary_relay, secondary_relay, synthetic_keys, + synthetic_public_identity, synthetic_public_key, }; - use nostr::{EventBuilder, EventId, Kind}; - use radroots_identity::{RadrootsIdentity, RadrootsIdentityPublic}; + use nostr::{EventBuilder, EventId, Keys, Kind}; + use radroots_identity::{PublicIdentity, PublicKey as IdentityPublicKey}; use radroots_nostr_connect::prelude::{ RadrootsNostrConnectMethod, RadrootsNostrConnectPermission, RadrootsNostrConnectRequest, RadrootsNostrConnectRequestMessage, @@ -672,9 +679,14 @@ mod tests { use std::sync::RwLock; use std::sync::atomic::{AtomicU8, Ordering}; - fn embedded_identity(index: u32) -> RadrootsIdentity { - RadrootsIdentity::from_secret_key_str(synthetic_secret_hex(index).as_str()) - .expect("identity") + fn embedded_identity(index: u32) -> Keys { + synthetic_keys(index) + } + + fn embedded_public_identity(keys: &Keys) -> PublicIdentity { + PublicIdentity::new( + IdentityPublicKey::from_hex(&keys.public_key().to_hex()).expect("identity public key"), + ) } fn expect_registration_required( @@ -720,7 +732,7 @@ mod tests { } struct StubBackend { - signer_identity: Option<RadrootsIdentityPublic>, + signer_identity: Option<PublicIdentity>, signer_identity_error: Option<&'static str>, sign_error_message: Option<&'static str>, } @@ -764,9 +776,7 @@ mod tests { } impl RadrootsNostrSignerBackend for StubBackend { - fn signer_identity( - &self, - ) -> Result<Option<RadrootsIdentityPublic>, RadrootsNostrSignerError> { + fn signer_identity(&self) -> Result<Option<PublicIdentity>, RadrootsNostrSignerError> { if let Some(message) = self.signer_identity_error { return Err(RadrootsNostrSignerError::InvalidState(message.into())); } @@ -775,7 +785,7 @@ mod tests { fn set_signer_identity( &self, - _signer_identity: RadrootsIdentityPublic, + _signer_identity: PublicIdentity, ) -> Result<(), RadrootsNostrSignerError> { unreachable!("set_signer_identity not used in tests") } @@ -1022,11 +1032,11 @@ mod tests { .signer_identity() .expect("signer identity") .expect("present"); - assert_eq!(signer_identity.id, identity.to_public().id); + assert_eq!(signer_identity, embedded_public_identity(&identity)); let capabilities = backend.capabilities().expect("capabilities"); let local = capabilities.local_signer.clone().expect("local signer"); - assert_eq!(local.public_identity.id, identity.to_public().id); + assert_eq!(local.public_identity, embedded_public_identity(&identity)); assert!(local.is_secret_backed()); assert!(capabilities.remote_sessions.is_empty()); assert_eq!(capabilities.all_signers().len(), 1); @@ -1037,9 +1047,9 @@ mod tests { .expect("stored signer identity"); assert!(same_public_identity_key( &manager_identity, - &identity.to_public() + &embedded_public_identity(&identity) )); - assert_eq!(backend.local_identity().public_key(), identity.public_key()); + assert_eq!(backend.local_keys().public_key(), identity.public_key()); } #[test] @@ -1065,7 +1075,7 @@ mod tests { fn embedded_backend_accepts_matching_manager_identity_and_setter_delegate() { let identity = embedded_identity(0x97); let manager = RadrootsNostrSignerManager::new_in_memory(); - let public_identity = identity.to_public(); + let public_identity = embedded_public_identity(&identity); manager .set_signer_identity(public_identity.clone()) .expect("prime manager identity"); @@ -1074,7 +1084,7 @@ mod tests { .expect("matching embedded backend"); let backend_trait: &dyn RadrootsNostrSignerBackend = &backend; - assert_eq!(backend.local_identity().public_key(), identity.public_key()); + assert_eq!(backend.local_keys().public_key(), identity.public_key()); assert!(same_public_identity_key( backend_trait .signer_identity() @@ -1638,7 +1648,7 @@ mod tests { assert_eq!(output.event.pubkey, identity.public_key()); let local = output.signer.local_account().expect("local signer"); - assert_eq!(local.public_identity.id, identity.to_public().id); + assert_eq!(local.public_identity, embedded_public_identity(&identity)); assert!(local.is_secret_backed()); } @@ -1712,9 +1722,7 @@ mod tests { let valid_identity = synthetic_public_identity(0xb2); assert!(same_public_identity_key(&valid_identity, &valid_identity)); - let mut valid_identity_with_different_hex = valid_identity.clone(); - valid_identity_with_different_hex.public_key_hex = - synthetic_public_identity(0xb3).public_key_hex; + let valid_identity_with_different_hex = synthetic_public_identity(0xb3); assert!(!same_public_identity_key( &valid_identity, &valid_identity_with_different_hex diff --git a/crates/nostr_signer/src/capability.rs b/crates/nostr_signer/src/capability.rs @@ -1,6 +1,6 @@ use crate::model::{RadrootsNostrSignerConnectionId, RadrootsNostrSignerConnectionRecord}; use nostr::RelayUrl; -use radroots_identity::{RadrootsIdentityId, RadrootsIdentityPublic}; +use radroots_identity::{AccountId, PublicIdentity}; use radroots_nostr_connect::prelude::RadrootsNostrConnectPermissions; use serde::{Deserialize, Serialize}; @@ -12,16 +12,16 @@ pub enum RadrootsNostrLocalSignerAvailability { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct RadrootsNostrLocalSignerCapability { - pub account_id: RadrootsIdentityId, - pub public_identity: RadrootsIdentityPublic, + pub account_id: AccountId, + pub public_identity: PublicIdentity, pub availability: RadrootsNostrLocalSignerAvailability, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct RadrootsNostrRemoteSessionSignerCapability { pub connection_id: RadrootsNostrSignerConnectionId, - pub signer_identity: RadrootsIdentityPublic, - pub user_identity: RadrootsIdentityPublic, + pub signer_identity: PublicIdentity, + pub user_identity: PublicIdentity, pub relays: Vec<RelayUrl>, pub permissions: RadrootsNostrConnectPermissions, } @@ -32,16 +32,14 @@ pub enum RadrootsNostrSignerCapability { RemoteSession(Box<RadrootsNostrRemoteSessionSignerCapability>), } -fn public_identity_eq(left: &RadrootsIdentityPublic, right: &RadrootsIdentityPublic) -> bool { - left.id == right.id - && left.public_key_hex == right.public_key_hex - && left.public_key_npub == right.public_key_npub +fn public_identity_eq(left: &PublicIdentity, right: &PublicIdentity) -> bool { + left == right } impl RadrootsNostrLocalSignerCapability { pub fn new( - account_id: RadrootsIdentityId, - public_identity: RadrootsIdentityPublic, + account_id: AccountId, + public_identity: PublicIdentity, availability: RadrootsNostrLocalSignerAvailability, ) -> Self { Self { @@ -59,8 +57,8 @@ impl RadrootsNostrLocalSignerCapability { impl RadrootsNostrRemoteSessionSignerCapability { pub fn new( connection_id: RadrootsNostrSignerConnectionId, - signer_identity: RadrootsIdentityPublic, - user_identity: RadrootsIdentityPublic, + signer_identity: PublicIdentity, + user_identity: PublicIdentity, ) -> Self { Self { connection_id, @@ -83,7 +81,7 @@ impl RadrootsNostrRemoteSessionSignerCapability { } impl RadrootsNostrSignerCapability { - pub fn public_identity(&self) -> &RadrootsIdentityPublic { + pub fn public_identity(&self) -> &PublicIdentity { match self { Self::LocalAccount(capability) => &capability.public_identity, Self::RemoteSession(capability) => &capability.user_identity, @@ -171,18 +169,13 @@ mod tests { fixture_alice_identity, fixture_bob_identity, fixture_carol_identity, fixture_diego_public_key, primary_relay, secondary_relay, }; - use radroots_identity::RadrootsIdentityPublic; + use radroots_identity::PublicIdentity; use radroots_nostr_connect::prelude::{ RadrootsNostrConnectMethod, RadrootsNostrConnectPermission, }; - fn assert_public_identity_matches( - actual: &RadrootsIdentityPublic, - expected: &RadrootsIdentityPublic, - ) { - assert_eq!(actual.id, expected.id); - assert_eq!(actual.public_key_hex, expected.public_key_hex); - assert_eq!(actual.public_key_npub, expected.public_key_npub); + fn assert_public_identity_matches(actual: &PublicIdentity, expected: &PublicIdentity) { + assert_eq!(actual, expected); } #[test] @@ -190,7 +183,7 @@ mod tests { let public_identity = fixture_alice_identity(); let capability = RadrootsNostrSignerCapability::LocalAccount(Box::new( RadrootsNostrLocalSignerCapability::new( - public_identity.id.clone(), + AccountId::from_public_identity(&public_identity), public_identity.clone(), RadrootsNostrLocalSignerAvailability::SecretBacked, ), @@ -260,46 +253,37 @@ mod tests { #[test] fn capability_equality_accounts_for_identity_fields_and_variant_kind() { let alice = fixture_alice_identity(); - let mut alice_with_different_hex = alice.clone(); - alice_with_different_hex.public_key_hex = fixture_bob_identity().public_key_hex; - let mut alice_with_different_npub = alice.clone(); - alice_with_different_npub.public_key_npub = fixture_bob_identity().public_key_npub; + let bob = fixture_bob_identity(); let local = RadrootsNostrLocalSignerCapability::new( - alice.id.clone(), + AccountId::from_public_identity(&alice), alice.clone(), RadrootsNostrLocalSignerAvailability::SecretBacked, ); let local_same = RadrootsNostrLocalSignerCapability::new( - alice.id.clone(), + AccountId::from_public_identity(&alice), alice.clone(), RadrootsNostrLocalSignerAvailability::SecretBacked, ); let local_changed_account = RadrootsNostrLocalSignerCapability::new( - fixture_bob_identity().id, + AccountId::from_public_identity(&bob), alice.clone(), RadrootsNostrLocalSignerAvailability::SecretBacked, ); let local_changed_availability = RadrootsNostrLocalSignerCapability::new( - alice.id.clone(), + AccountId::from_public_identity(&alice), alice.clone(), RadrootsNostrLocalSignerAvailability::PublicOnly, ); - let local_changed_hex = RadrootsNostrLocalSignerCapability::new( - alice.id.clone(), - alice_with_different_hex, - RadrootsNostrLocalSignerAvailability::SecretBacked, - ); - let local_changed = RadrootsNostrLocalSignerCapability::new( - alice.id.clone(), - alice_with_different_npub, + let local_changed_identity = RadrootsNostrLocalSignerCapability::new( + AccountId::from_public_identity(&alice), + bob, RadrootsNostrLocalSignerAvailability::SecretBacked, ); assert_eq!(local, local_same); assert_ne!(local, local_changed_account); assert_ne!(local, local_changed_availability); - assert_ne!(local, local_changed_hex); - assert_ne!(local, local_changed); + assert_ne!(local, local_changed_identity); let remote = RadrootsNostrRemoteSessionSignerCapability::new( RadrootsNostrSignerConnectionId::new_v7(), @@ -323,16 +307,15 @@ mod tests { .into(), ); let mut remote_changed_signer = remote.clone(); - remote_changed_signer.signer_identity.public_key_hex = - fixture_alice_identity().public_key_hex; - let mut remote_changed = remote.clone(); - remote_changed.user_identity.public_key_npub = fixture_alice_identity().public_key_npub; + remote_changed_signer.signer_identity = fixture_alice_identity(); + let mut remote_changed_user = remote.clone(); + remote_changed_user.user_identity = fixture_alice_identity(); assert_eq!(remote, remote_same); assert_ne!(remote, remote_changed_connection); assert_ne!(remote, remote_changed_relays); assert_ne!(remote, remote_changed_permissions); assert_ne!(remote, remote_changed_signer); - assert_ne!(remote, remote_changed); + assert_ne!(remote, remote_changed_user); assert_eq!( RadrootsNostrSignerCapability::LocalAccount(Box::new(local.clone())), @@ -344,27 +327,16 @@ mod tests { ); assert_ne!( RadrootsNostrSignerCapability::LocalAccount(Box::new(local)), - RadrootsNostrSignerCapability::RemoteSession(Box::new(remote_changed)) + RadrootsNostrSignerCapability::RemoteSession(Box::new(remote_changed_user)) ); } #[test] - fn public_identity_eq_covers_field_level_short_circuits() { + fn public_identity_eq_compares_invariant_checked_values() { let alice = fixture_alice_identity(); let bob = fixture_bob_identity(); - let mut different_id = alice.clone(); - different_id.id = bob.id.clone(); - assert!(!public_identity_eq(&alice, &different_id)); - - let mut different_hex = alice.clone(); - different_hex.public_key_hex = bob.public_key_hex.clone(); - assert!(!public_identity_eq(&alice, &different_hex)); - - let mut different_npub = alice.clone(); - different_npub.public_key_npub = bob.public_key_npub.clone(); - assert!(!public_identity_eq(&alice, &different_npub)); - + assert!(!public_identity_eq(&alice, &bob)); assert!(public_identity_eq(&alice, &alice)); } } diff --git a/crates/nostr_signer/src/evaluation.rs b/crates/nostr_signer/src/evaluation.rs @@ -5,7 +5,7 @@ use crate::model::{ RadrootsNostrSignerRequestAuditRecord, RadrootsNostrSignerRequestId, }; use nostr::{PublicKey, RelayUrl}; -use radroots_identity::RadrootsIdentityPublic; +use radroots_identity::PublicIdentity; use radroots_nostr_connect::prelude::{ RadrootsNostrConnectClientMetadata, RadrootsNostrConnectMethod, RadrootsNostrConnectPermission, RadrootsNostrConnectPermissions, RadrootsNostrConnectRemoteSessionCapability, @@ -69,7 +69,7 @@ pub struct RadrootsNostrSignerRequestEvaluation { impl RadrootsNostrSignerConnectProposal { pub fn into_connection_draft( self, - user_identity: RadrootsIdentityPublic, + user_identity: PublicIdentity, ) -> RadrootsNostrSignerConnectionDraft { let mut draft = RadrootsNostrSignerConnectionDraft::new(self.client_public_key, user_identity) @@ -207,14 +207,10 @@ fn sign_event_kind_suffix(value: &str) -> &str { value.strip_prefix("kind:").unwrap_or(value) } -fn identity_public_key( - identity: &RadrootsIdentityPublic, -) -> Result<PublicKey, RadrootsNostrSignerError> { - PublicKey::parse(identity.public_key_hex.as_str()) - .or_else(|_| PublicKey::from_hex(identity.public_key_hex.as_str())) - .map_err(|_| { - RadrootsNostrSignerError::InvalidState("user identity public key is invalid".into()) - }) +fn identity_public_key(identity: &PublicIdentity) -> Result<PublicKey, RadrootsNostrSignerError> { + PublicKey::from_hex(&identity.public_key().to_hex()).map_err(|_| { + RadrootsNostrSignerError::InvalidState("user identity public key is invalid".into()) + }) } #[cfg(test)] @@ -223,17 +219,11 @@ mod tests { use super::*; use crate::test_support::{ api_primary_https, fixture_alice_identity, fixture_alice_public_key, fixture_bob_identity, - fixture_carol_public_key, fixture_diego_identity, primary_relay, synthetic_public_identity, - synthetic_public_key, + fixture_carol_public_key, fixture_diego_identity, primary_relay, synthetic_public_key, }; use nostr::{PublicKey, Timestamp, UnsignedEvent}; - use radroots_identity::RadrootsIdentityPublic; use serde_json::json; - fn public_identity(index: u32) -> RadrootsIdentityPublic { - synthetic_public_identity(index) - } - fn public_key(index: u32) -> PublicKey { synthetic_public_key(index) } @@ -299,7 +289,7 @@ mod tests { match hint { RadrootsNostrSignerRequestResponseHint::RemoteSessionCapability(capability) => { let expected_public_key = - PublicKey::parse(fixture_diego_identity().public_key_hex.as_str()) + PublicKey::from_hex(&fixture_diego_identity().public_key().to_hex()) .expect("user public key"); assert_eq!( capability.user_public_key.to_hex(), @@ -561,38 +551,4 @@ mod tests { RadrootsNostrSignerRequestResponseHint::RelayList(vec![primary_relay()]) ); } - - #[test] - fn invalid_identity_public_key_returns_invalid_state() { - let mut identity = public_identity(9); - identity.public_key_hex = "invalid".into(); - - let err = identity_public_key(&identity).expect_err("invalid identity"); - assert!( - err.to_string() - .contains("user identity public key is invalid") - ); - - let mut invalid_connection = connection(); - invalid_connection.user_identity.public_key_hex = "invalid".into(); - let err = response_hint_for_request( - &invalid_connection, - &RadrootsNostrConnectRequest::GetPublicKey, - ) - .expect_err("invalid get_public_key response hint"); - assert!( - err.to_string() - .contains("user identity public key is invalid") - ); - - let err = response_hint_for_request( - &invalid_connection, - &RadrootsNostrConnectRequest::GetSessionCapability, - ) - .expect_err("invalid get_session_capability response hint"); - assert!( - err.to_string() - .contains("user identity public key is invalid") - ); - } } diff --git a/crates/nostr_signer/src/manager.rs b/crates/nostr_signer/src/manager.rs @@ -19,7 +19,7 @@ use crate::model::{ }; use crate::store::{RadrootsNostrMemorySignerStore, RadrootsNostrSignerStore}; use nostr::{PublicKey, RelayUrl}; -use radroots_identity::RadrootsIdentityPublic; +use radroots_identity::PublicIdentity; use radroots_nostr_connect::prelude::{ RadrootsNostrConnectClientMetadata, RadrootsNostrConnectMethod, RadrootsNostrConnectPermissions, RadrootsNostrConnectRequest, @@ -57,9 +57,7 @@ impl RadrootsNostrSignerManager { }) } - pub fn signer_identity( - &self, - ) -> Result<Option<RadrootsIdentityPublic>, RadrootsNostrSignerError> { + pub fn signer_identity(&self) -> Result<Option<PublicIdentity>, RadrootsNostrSignerError> { let guard = self .state .read() @@ -69,7 +67,7 @@ impl RadrootsNostrSignerManager { pub fn set_signer_identity( &self, - signer_identity: RadrootsIdentityPublic, + signer_identity: PublicIdentity, ) -> Result<(), RadrootsNostrSignerError> { validate_public_identity(&signer_identity)?; self.update_state(|state| { @@ -289,11 +287,11 @@ impl RadrootsNostrSignerManager { if state.connections.iter().any(|record| { !record.is_terminal() && record.client_public_key == draft.client_public_key - && record.user_identity.id == draft.user_identity.id + && record.user_identity.id() == draft.user_identity.id() }) { return Err(RadrootsNostrSignerError::ConnectionAlreadyExists { client_public_key: draft.client_public_key.to_hex(), - user_identity_id: draft.user_identity.id.to_string(), + user_identity_id: draft.user_identity.id().to_string(), }); } @@ -1026,14 +1024,7 @@ fn ensure_no_active_publish_workflow( Ok(()) } -fn validate_public_identity( - identity: &RadrootsIdentityPublic, -) -> Result<(), RadrootsNostrSignerError> { - if identity.id.as_str() != identity.public_key_hex { - return Err(RadrootsNostrSignerError::InvalidState( - "public identity id does not match public key".into(), - )); - } +fn validate_public_identity(_identity: &PublicIdentity) -> Result<(), RadrootsNostrSignerError> { Ok(()) } @@ -1174,13 +1165,11 @@ fn request_decision( } fn parse_identity_public_key( - identity: &RadrootsIdentityPublic, + identity: &PublicIdentity, ) -> Result<PublicKey, RadrootsNostrSignerError> { - PublicKey::parse(identity.public_key_hex.as_str()) - .or_else(|_| PublicKey::from_hex(identity.public_key_hex.as_str())) - .map_err(|_| { - RadrootsNostrSignerError::InvalidState("identity public key is invalid".into()) - }) + PublicKey::from_hex(&identity.public_key().to_hex()).map_err(|_| { + RadrootsNostrSignerError::InvalidState("identity public key is invalid".into()) + }) } fn now_unix_secs() -> u64 { @@ -1226,23 +1215,16 @@ mod tests { synthetic_public_identity, synthetic_public_key, tertiary_relay, }; use nostr::{PublicKey, Timestamp, UnsignedEvent}; - use radroots_identity::RadrootsIdentityPublic; + use radroots_identity::PublicIdentity; use radroots_nostr_connect::prelude::RadrootsNostrConnectPermission; use serde_json::json; use std::sync::Arc; use std::thread; - fn public_identity(index: u32) -> RadrootsIdentityPublic { + fn public_identity(index: u32) -> PublicIdentity { synthetic_public_identity(index) } - fn invalid_public_identity(index: u32) -> RadrootsIdentityPublic { - let mut identity = public_identity(index); - identity.id = - radroots_identity::RadrootsIdentityId::parse(&public_key(0xff).to_hex()).expect("id"); - identity - } - fn public_key(index: u32) -> PublicKey { synthetic_public_key(index) } @@ -1369,10 +1351,8 @@ mod tests { .join(); } - fn assert_same_public_identity(left: &RadrootsIdentityPublic, right: &RadrootsIdentityPublic) { - assert_eq!(left.id.as_str(), right.id.as_str()); - assert_eq!(left.public_key_hex, right.public_key_hex); - assert_eq!(left.public_key_npub, right.public_key_npub); + fn assert_same_public_identity(left: &PublicIdentity, right: &PublicIdentity) { + assert_eq!(left, right); } fn assert_same_connection( @@ -1529,7 +1509,7 @@ mod tests { } #[test] - fn set_signer_identity_validates_and_persists() { + fn set_signer_identity_persists_invariant_checked_value() { let manager = RadrootsNostrSignerManager::new_in_memory(); let signer_identity = fixture_alice_identity(); manager @@ -1541,14 +1521,6 @@ mod tests { .expect("identity") .expect("loaded"); assert_same_public_identity(&loaded, &signer_identity); - - let err = manager - .set_signer_identity(invalid_public_identity(0x2)) - .expect_err("invalid identity"); - assert!( - err.to_string() - .contains("public identity id does not match public key") - ); } #[test] @@ -1673,18 +1645,6 @@ mod tests { .to_string() .contains("connect secret already in use") ); - - let invalid_user = manager - .register_connection(RadrootsNostrSignerConnectionDraft::new( - public_key(0x13), - invalid_public_identity(0x14), - )) - .expect_err("invalid user identity"); - assert!( - invalid_user - .to_string() - .contains("public identity id does not match public key") - ); } #[test] @@ -2989,41 +2949,6 @@ mod tests { ); assert!(evaluation.connection.pending_request.is_none()); - let (invalid_identity_eval_record, invalid_identity_eval_workflow, _) = - start_auth_replay_workflow(10, "req-eval-invalid-identity"); - { - let mut state = manager.state.write().expect("write"); - let pending_request = RadrootsNostrSignerPendingRequest::new( - request_message_with_request( - "req-eval-invalid-identity", - RadrootsNostrConnectRequest::GetSessionCapability, - ), - 81, - ) - .expect("pending request"); - let workflow = state - .publish_workflows - .iter_mut() - .find(|workflow| workflow.workflow_id == invalid_identity_eval_workflow.workflow_id) - .expect("stored workflow"); - workflow.pending_request = Some(pending_request.clone()); - let record = state - .connections - .iter_mut() - .find(|record| record.connection_id == invalid_identity_eval_record.connection_id) - .expect("stored connection"); - record.pending_request = Some(pending_request); - record.user_identity.public_key_hex = "invalid".into(); - } - let invalid_identity_eval_err = manager - .evaluate_auth_replay_publish_workflow(&invalid_identity_eval_workflow.workflow_id) - .expect_err("invalid identity evaluate"); - assert!( - invalid_identity_eval_err - .to_string() - .contains("user identity public key is invalid") - ); - let (terminal_eval_record, terminal_eval_workflow, _) = start_auth_replay_workflow(2, "req-eval-terminal"); { @@ -3455,28 +3380,6 @@ mod tests { } #[test] - fn register_connection_rejects_invalid_persisted_signer_identity() { - let store = Arc::new(RadrootsNostrMemorySignerStore::new()); - let state = RadrootsNostrSignerStoreState { - signer_identity: Some(invalid_public_identity(0x54)), - ..Default::default() - }; - store.save(&state).expect("seed state"); - - let manager = RadrootsNostrSignerManager::new(store).expect("manager"); - let err = manager - .register_connection(RadrootsNostrSignerConnectionDraft::new( - public_key(0x55), - public_identity(0x56), - )) - .expect_err("invalid signer identity"); - assert!( - err.to_string() - .contains("public identity id does not match public key") - ); - } - - #[test] fn manager_reports_poisoned_state_lock() { let manager = RadrootsNostrSignerManager::new_in_memory(); poison_manager_state(&manager); @@ -3555,8 +3458,8 @@ mod tests { .evaluate_connect_request( public_key(0x58), RadrootsNostrConnectRequest::Connect { - remote_signer_public_key: PublicKey::parse( - signer_identity.public_key_hex.as_str(), + remote_signer_public_key: PublicKey::from_hex( + &signer_identity.public_key().to_hex(), ) .expect("signer public key"), secret: Some("secret".into()), @@ -3755,7 +3658,7 @@ mod tests { let manager = RadrootsNostrSignerManager::new_in_memory(); let signer_identity = public_identity(0x60); let signer_public_key = - PublicKey::parse(signer_identity.public_key_hex.as_str()).expect("signer public key"); + PublicKey::from_hex(&signer_identity.public_key().to_hex()).expect("signer public key"); manager .set_signer_identity(signer_identity) .expect("set signer"); @@ -3930,34 +3833,6 @@ mod tests { .to_string() .contains("different client public key") ); - - let store = Arc::new(RadrootsNostrMemorySignerStore::new()); - let mut invalid_identity = public_identity(0x69); - invalid_identity.public_key_hex = "invalid".into(); - let invalid_state = RadrootsNostrSignerStoreState { - signer_identity: Some(invalid_identity), - ..Default::default() - }; - store - .save(&invalid_state) - .expect("save invalid signer state"); - let invalid_manager = RadrootsNostrSignerManager::new(store).expect("invalid manager"); - let invalid_signer_err = invalid_manager - .evaluate_connect_request( - public_key(0x70), - RadrootsNostrConnectRequest::Connect { - remote_signer_public_key: signer_public_key, - secret: None, - requested_permissions: RadrootsNostrConnectPermissions::default(), - client_metadata: None, - }, - ) - .expect_err("invalid signer public key"); - assert!( - invalid_signer_err - .to_string() - .contains("identity public key is invalid") - ); } #[test] @@ -4176,25 +4051,5 @@ mod tests { ) .expect_err("invalid pending request"); assert!(invalid_pending.to_string().contains("invalid request id")); - - let mut invalid_user_record = RadrootsNostrSignerConnectionRecord::new( - RadrootsNostrSignerConnectionId::new_v7(), - public_identity(0x87), - RadrootsNostrSignerConnectionDraft::new(public_key(0x88), public_identity(0x89)), - 1, - ); - invalid_user_record.status = RadrootsNostrSignerConnectionStatus::Active; - invalid_user_record.user_identity.public_key_hex = "invalid".into(); - let response_hint_err = evaluate_request_action( - &mut invalid_user_record, - &request_message_with_request("req-get", RadrootsNostrConnectRequest::GetPublicKey), - 1, - ) - .expect_err("invalid response hint"); - assert!( - response_hint_err - .to_string() - .contains("user identity public key is invalid") - ); } } diff --git a/crates/nostr_signer/src/model.rs b/crates/nostr_signer/src/model.rs @@ -1,7 +1,7 @@ use crate::error::RadrootsNostrSignerError; use hex::encode as hex_encode; use nostr::{PublicKey, RelayUrl}; -use radroots_identity::RadrootsIdentityPublic; +use radroots_identity::PublicIdentity; use radroots_nostr_connect::prelude::{ RadrootsNostrConnectClientMetadata, RadrootsNostrConnectMethod, RadrootsNostrConnectPermission, RadrootsNostrConnectPermissions, RadrootsNostrConnectRequestMessage, @@ -120,7 +120,7 @@ pub struct RadrootsNostrSignerPermissionGrant { #[derive(Debug, Clone)] pub struct RadrootsNostrSignerConnectionDraft { pub client_public_key: PublicKey, - pub user_identity: RadrootsIdentityPublic, + pub user_identity: PublicIdentity, pub connect_secret: Option<String>, pub client_metadata: Option<RadrootsNostrConnectClientMetadata>, pub requested_permissions: RadrootsNostrConnectPermissions, @@ -132,8 +132,8 @@ pub struct RadrootsNostrSignerConnectionDraft { pub struct RadrootsNostrSignerConnectionRecord { pub connection_id: RadrootsNostrSignerConnectionId, pub client_public_key: PublicKey, - pub signer_identity: RadrootsIdentityPublic, - pub user_identity: RadrootsIdentityPublic, + pub signer_identity: PublicIdentity, + pub user_identity: PublicIdentity, #[serde( default, alias = "connect_secret", @@ -197,7 +197,7 @@ pub struct RadrootsNostrSignerPublishWorkflowRecord { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct RadrootsNostrSignerStoreState { pub version: u32, - pub signer_identity: Option<RadrootsIdentityPublic>, + pub signer_identity: Option<PublicIdentity>, pub connections: Vec<RadrootsNostrSignerConnectionRecord>, pub audit_records: Vec<RadrootsNostrSignerRequestAuditRecord>, #[serde(default)] @@ -456,7 +456,7 @@ impl RadrootsNostrSignerPermissionGrant { } impl RadrootsNostrSignerConnectionDraft { - pub fn new(client_public_key: PublicKey, user_identity: RadrootsIdentityPublic) -> Self { + pub fn new(client_public_key: PublicKey, user_identity: PublicIdentity) -> Self { Self { client_public_key, user_identity, @@ -506,7 +506,7 @@ impl RadrootsNostrSignerConnectionDraft { impl RadrootsNostrSignerConnectionRecord { pub fn new( connection_id: RadrootsNostrSignerConnectionId, - signer_identity: RadrootsIdentityPublic, + signer_identity: PublicIdentity, draft: RadrootsNostrSignerConnectionDraft, created_at_unix: u64, ) -> Self { @@ -771,12 +771,12 @@ mod tests { primary_relay, synthetic_public_identity, synthetic_public_key, }; use nostr::PublicKey; - use radroots_identity::RadrootsIdentityPublic; + use radroots_identity::PublicIdentity; use serde_json::json; use std::str::FromStr; use tempfile::tempdir; - fn public_identity(index: u32) -> RadrootsIdentityPublic { + fn public_identity(index: u32) -> PublicIdentity { synthetic_public_identity(index) } diff --git a/crates/nostr_signer/src/nip46.rs b/crates/nostr_signer/src/nip46.rs @@ -2,7 +2,7 @@ use nostr::{ UnsignedEvent, filter::{Alphabet, SingleLetterTag}, }; -use radroots_identity::RadrootsIdentityPublic; +use radroots_identity::PublicIdentity; use radroots_nostr::prelude::{ RadrootsNostrEvent, RadrootsNostrFilter, RadrootsNostrGenericEventBuilder, RadrootsNostrKind, RadrootsNostrPublicKey, RadrootsNostrRelayUrl, RadrootsNostrTag, RadrootsNostrTimestamp, @@ -42,7 +42,7 @@ pub trait RadrootsNostrSignerNip46Signer: Clone + Send + Sync { client_public_key: &RadrootsNostrPublicKey, payload: &str, ) -> Result<String, RadrootsNostrSignerError>; - fn user_identity(&self) -> RadrootsIdentityPublic; + fn user_identity(&self) -> PublicIdentity; /// Signs a caller-supplied NIP-46 unsigned event without claiming typed /// Radroots product authoring. fn sign_user_event( @@ -206,7 +206,7 @@ impl<S: RadrootsNostrSignerNip46Signer> RadrootsNostrSignerNip46Codec<S> { &self, unsigned_event: UnsignedEvent, ) -> RadrootsNostrConnectResponse { - let user_public_key = self.signer.user_identity().public_key_hex; + let user_public_key = self.signer.user_identity().public_key().to_hex(); if unsigned_event.pubkey.to_hex() != user_public_key { return RadrootsNostrConnectResponse::Error { result: None, @@ -853,8 +853,8 @@ mod tests { }; use crate::store::RadrootsNostrSignerStore; use crate::test_support::{fixture_alice_identity, fixture_carol_public_key, primary_relay}; - use nostr::{Keys, Timestamp, UnsignedEvent}; - use radroots_identity::{RadrootsIdentity, RadrootsIdentityPublic}; + use nostr::{Keys, SecretKey, Timestamp, UnsignedEvent}; + use radroots_identity::{PublicIdentity, PublicKey as IdentityPublicKey}; use radroots_nostr::prelude::{ RadrootsNostrEvent, RadrootsNostrGenericEventBuilder, RadrootsNostrKind, RadrootsNostrPublicKey, RadrootsNostrTagKind, @@ -872,8 +872,8 @@ mod tests { #[derive(Clone)] struct TestSigner { - signer_identity: RadrootsIdentity, - user_identity: RadrootsIdentity, + signer_identity: Keys, + user_identity: Keys, sign_events: bool, fail_crypto: bool, } @@ -948,8 +948,8 @@ mod tests { Ok(payload.to_owned()) } - fn user_identity(&self) -> RadrootsIdentityPublic { - self.user_identity.to_public() + fn user_identity(&self) -> PublicIdentity { + public_identity_from_keys(&self.user_identity) } fn sign_user_event( @@ -958,7 +958,7 @@ mod tests { ) -> Result<RadrootsNostrEvent, RadrootsNostrSignerError> { if self.sign_events { return unsigned_event - .sign_with_keys(self.user_identity.keys()) + .sign_with_keys(&self.user_identity) .map_err(|error| RadrootsNostrSignerError::Sign(error.to_string())); } Err(RadrootsNostrSignerError::Sign( @@ -1069,16 +1069,24 @@ mod tests { test_signer_with_options(false, false) } + fn keys_from_secret(secret_key_hex: &str) -> Keys { + Keys::new(SecretKey::from_hex(secret_key_hex).expect("secret key")) + } + + fn public_identity_from_keys(keys: &Keys) -> PublicIdentity { + PublicIdentity::new( + IdentityPublicKey::from_hex(&keys.public_key().to_hex()).expect("identity public key"), + ) + } + fn test_signer_with_options(sign_events: bool, fail_crypto: bool) -> TestSigner { TestSigner { - signer_identity: RadrootsIdentity::from_secret_key_str( + signer_identity: keys_from_secret( "1111111111111111111111111111111111111111111111111111111111111111", - ) - .expect("signer identity"), - user_identity: RadrootsIdentity::from_secret_key_str( + ), + user_identity: keys_from_secret( "2222222222222222222222222222222222222222222222222222222222222222", - ) - .expect("user identity"), + ), sign_events, fail_crypto, } @@ -2010,17 +2018,15 @@ mod tests { backend .register_connection(RadrootsNostrSignerConnectionDraft::new( client_public_key, - test_signer().user_identity.to_public(), + test_signer().user_identity(), )) .expect("first connection"); backend .register_connection(RadrootsNostrSignerConnectionDraft::new( client_public_key, - RadrootsIdentity::from_secret_key_str( + public_identity_from_keys(&keys_from_secret( "3333333333333333333333333333333333333333333333333333333333333333", - ) - .expect("second user identity") - .to_public(), + )), )) .expect("second connection"); @@ -2119,7 +2125,7 @@ mod tests { let response = codec .sign_event_response( serde_json::from_value(serde_json::json!({ - "pubkey": fixture_alice_identity().public_key_hex, + "pubkey": fixture_alice_identity().public_key().to_hex(), "created_at": 1, "kind": 1, "tags": [], @@ -2188,8 +2194,8 @@ mod tests { | RadrootsNostrSignerAuthState::Authorized )); assert_eq!( - connection.user_identity.id, - test_signer().user_identity().id + connection.user_identity.id(), + test_signer().user_identity().id() ); } } diff --git a/crates/nostr_signer/src/store.rs b/crates/nostr_signer/src/store.rs @@ -23,7 +23,7 @@ use crate::sqlite::RadrootsNostrSignerSqliteDb; #[cfg(feature = "native")] use nostr::RelayUrl; #[cfg(feature = "native")] -use radroots_identity::RadrootsIdentityPublic; +use radroots_identity::PublicIdentity; #[cfg(feature = "native")] use radroots_nostr_connect::prelude::{ RadrootsNostrConnectClientMetadata, RadrootsNostrConnectMethod, RadrootsNostrConnectPermission, @@ -159,7 +159,7 @@ impl RadrootsNostrSignerStore for RadrootsNostrSqliteSignerStore { signer_identity: metadata .signer_identity_json .as_deref() - .map(parse_json_field::<RadrootsIdentityPublic>) + .map(parse_json_field::<PublicIdentity>) .transpose()?, connections: Vec::new(), audit_records: Vec::new(), @@ -297,11 +297,11 @@ impl RadrootsNostrSignerStore for RadrootsNostrSqliteSignerStore { state .signer_identity .as_ref() - .map(|identity| identity.id.to_string()), + .map(|identity| identity.id().to_string()), state .signer_identity .as_ref() - .map(|identity| identity.public_key_hex.clone()), + .map(|identity| identity.public_key().to_hex()), state .signer_identity .as_ref() @@ -317,11 +317,11 @@ impl RadrootsNostrSignerStore for RadrootsNostrSqliteSignerStore { json!([ connection.connection_id.as_str(), connection.client_public_key.to_hex(), - connection.signer_identity.id.to_string(), - connection.signer_identity.public_key_hex.clone(), + connection.signer_identity.id().to_string(), + connection.signer_identity.public_key().to_hex(), serde_json::to_string(&connection.signer_identity)?, - connection.user_identity.id.to_string(), - connection.user_identity.public_key_hex.clone(), + connection.user_identity.id().to_string(), + connection.user_identity.public_key().to_hex(), serde_json::to_string(&connection.user_identity)?, connection .connect_secret_hash diff --git a/crates/nostr_signer/src/test_support.rs b/crates/nostr_signer/src/test_support.rs @@ -3,12 +3,13 @@ use crate::test_fixtures::{ FIXTURE_DIEGO, RELAY_PRIMARY_WSS, RELAY_SECONDARY_WSS, RELAY_TERTIARY_WSS, }; use nostr::{Keys, PublicKey, RelayUrl, SecretKey}; -use radroots_identity::{RadrootsIdentity, RadrootsIdentityPublic}; +use radroots_identity::{PublicIdentity, PublicKey as IdentityPublicKey}; -fn approved_public_identity(identity: ApprovedFixtureIdentity) -> RadrootsIdentityPublic { - RadrootsIdentity::from_secret_key_str(identity.secret_key_hex) - .expect("identity") - .to_public() +fn approved_public_identity(identity: ApprovedFixtureIdentity) -> PublicIdentity { + let public_key = approved_public_key(identity); + PublicIdentity::new( + IdentityPublicKey::from_hex(&public_key.to_hex()).expect("identity public key"), + ) } fn approved_public_key(identity: ApprovedFixtureIdentity) -> PublicKey { @@ -20,7 +21,7 @@ fn relay(url: &str) -> RelayUrl { RelayUrl::parse(url).expect("relay") } -pub(crate) fn fixture_alice_identity() -> RadrootsIdentityPublic { +pub(crate) fn fixture_alice_identity() -> PublicIdentity { approved_public_identity(FIXTURE_ALICE) } @@ -28,11 +29,11 @@ pub(crate) fn fixture_alice_public_key() -> PublicKey { approved_public_key(FIXTURE_ALICE) } -pub(crate) fn fixture_bob_identity() -> RadrootsIdentityPublic { +pub(crate) fn fixture_bob_identity() -> PublicIdentity { approved_public_identity(FIXTURE_BOB) } -pub(crate) fn fixture_carol_identity() -> RadrootsIdentityPublic { +pub(crate) fn fixture_carol_identity() -> PublicIdentity { approved_public_identity(FIXTURE_CAROL) } @@ -40,7 +41,7 @@ pub(crate) fn fixture_carol_public_key() -> PublicKey { approved_public_key(FIXTURE_CAROL) } -pub(crate) fn fixture_diego_identity() -> RadrootsIdentityPublic { +pub(crate) fn fixture_diego_identity() -> PublicIdentity { approved_public_identity(FIXTURE_DIEGO) } @@ -68,11 +69,11 @@ pub(crate) fn synthetic_secret_hex(index: u32) -> String { format!("{index:064x}") } -pub(crate) fn synthetic_public_identity(index: u32) -> RadrootsIdentityPublic { - let secret_hex = synthetic_secret_hex(index); - RadrootsIdentity::from_secret_key_str(secret_hex.as_str()) - .expect("identity") - .to_public() +pub(crate) fn synthetic_public_identity(index: u32) -> PublicIdentity { + let public_key = synthetic_public_key(index); + PublicIdentity::new( + IdentityPublicKey::from_hex(&public_key.to_hex()).expect("identity public key"), + ) } pub(crate) fn synthetic_public_key(index: u32) -> PublicKey { @@ -80,3 +81,9 @@ pub(crate) fn synthetic_public_key(index: u32) -> PublicKey { let secret = SecretKey::from_hex(secret_hex.as_str()).expect("secret"); Keys::new(secret).public_key() } + +pub(crate) fn synthetic_keys(index: u32) -> Keys { + let secret_hex = synthetic_secret_hex(index); + let secret = SecretKey::from_hex(secret_hex.as_str()).expect("secret"); + Keys::new(secret) +} diff --git a/crates/outbox/Cargo.toml b/crates/outbox/Cargo.toml @@ -34,6 +34,9 @@ sqlx = { workspace = true, optional = true, features = ["derive"] } thiserror = { workspace = true } [dev-dependencies] +radroots_identity = { workspace = true, default-features = false, features = [ + "std", +] } radroots_nostr = { workspace = true, default-features = false, features = [ "std", "events", diff --git a/crates/outbox/src/store.rs b/crates/outbox/src/store.rs @@ -161,7 +161,7 @@ impl RadrootsOutbox { prepare_delivery_plan(input.draft.expected_event_id_str(), &input.delivery_plan)?; let operation_digest = operation_idempotency_digest( input.operation_kind.as_str(), - input.draft.expected_pubkey_str(), + &input.draft.expected_pubkey().to_hex(), &input.draft, ); @@ -169,7 +169,7 @@ impl RadrootsOutbox { && let Some(existing) = existing_idempotent_operation_for_pool( &self.pool, input.operation_kind.as_str(), - input.draft.expected_pubkey_str(), + &input.draft.expected_pubkey().to_hex(), idempotency_key, ) .await? @@ -177,7 +177,7 @@ impl RadrootsOutbox { { return Err(RadrootsOutboxError::IdempotencyConflict { operation_kind: input.operation_kind.clone(), - expected_pubkey: input.draft.expected_pubkey_str().to_owned(), + expected_pubkey: input.draft.expected_pubkey().to_hex().to_owned(), idempotency_key: idempotency_key.to_owned(), existing_digest: existing.operation_idempotency_digest, new_digest: operation_digest, @@ -205,14 +205,14 @@ impl RadrootsOutbox { prepare_delivery_plan(input.draft.expected_event_id_str(), &input.delivery_plan)?; let operation_digest = trade_mutation_operation_idempotency_digest( input.operation_kind.as_str(), - input.draft.expected_pubkey_str(), + &input.draft.expected_pubkey().to_hex(), &semantic, ); if let Some(existing) = existing_trade_mutation_operation_for_pool( &self.pool, input.operation_kind.as_str(), - input.draft.expected_pubkey_str(), + &input.draft.expected_pubkey().to_hex(), input.mutation_id.as_str(), ) .await? @@ -220,7 +220,7 @@ impl RadrootsOutbox { { return Err(RadrootsOutboxError::IdempotencyConflict { operation_kind: input.operation_kind.clone(), - expected_pubkey: input.draft.expected_pubkey_str().to_owned(), + expected_pubkey: input.draft.expected_pubkey().to_hex().to_owned(), idempotency_key: input.mutation_id.to_string(), existing_digest: existing.operation_idempotency_digest, new_digest: operation_digest, @@ -231,7 +231,7 @@ impl RadrootsOutbox { && let Some(existing) = existing_idempotent_operation_for_pool( &self.pool, input.operation_kind.as_str(), - input.draft.expected_pubkey_str(), + &input.draft.expected_pubkey().to_hex(), idempotency_key, ) .await? @@ -239,7 +239,7 @@ impl RadrootsOutbox { { return Err(RadrootsOutboxError::IdempotencyConflict { operation_kind: input.operation_kind.clone(), - expected_pubkey: input.draft.expected_pubkey_str().to_owned(), + expected_pubkey: input.draft.expected_pubkey().to_hex().to_owned(), idempotency_key: idempotency_key.to_owned(), existing_digest: existing.operation_idempotency_digest, new_digest: operation_digest, @@ -261,7 +261,7 @@ impl RadrootsOutbox { prepare_delivery_plan(input.draft.expected_event_id_str(), &input.delivery_plan)?; let operation_digest = operation_idempotency_digest( input.operation_kind.as_str(), - input.draft.expected_pubkey_str(), + &input.draft.expected_pubkey().to_hex(), &input.draft, ); let mut tx = self.pool.begin().await?; @@ -270,7 +270,7 @@ impl RadrootsOutbox { && let Some(existing) = existing_idempotent_operation( &mut tx, input.operation_kind.as_str(), - input.draft.expected_pubkey_str(), + &input.draft.expected_pubkey().to_hex(), idempotency_key, ) .await? @@ -278,7 +278,7 @@ impl RadrootsOutbox { if existing.operation_idempotency_digest != operation_digest { return Err(RadrootsOutboxError::IdempotencyConflict { operation_kind: input.operation_kind, - expected_pubkey: input.draft.expected_pubkey_str().to_owned(), + expected_pubkey: input.draft.expected_pubkey().to_hex().to_owned(), idempotency_key: idempotency_key.to_owned(), existing_digest: existing.operation_idempotency_digest, new_digest: operation_digest, @@ -311,7 +311,7 @@ impl RadrootsOutbox { "INSERT INTO outbox_operations(operation_kind, expected_pubkey, semantic_scope, trade_id, mutation_id, canonical_payload_sha256, idempotency_key, operation_idempotency_digest, status, created_at_ms, updated_at_ms) VALUES (?, ?, 'generic_event', NULL, NULL, NULL, ?, ?, ?, ?, ?)", ) .bind(input.operation_kind.as_str()) - .bind(input.draft.expected_pubkey_str()) + .bind(input.draft.expected_pubkey().to_hex()) .bind(input.idempotency_key.as_deref()) .bind(operation_digest.as_str()) .bind(RadrootsOutboxOperationStatus::Queued.as_str()) @@ -326,7 +326,7 @@ impl RadrootsOutbox { ) .bind(operation_id) .bind(input.draft.expected_event_id_str()) - .bind(input.draft.expected_pubkey_str()) + .bind(input.draft.expected_pubkey().to_hex()) .bind(draft_json.as_str()) .bind(RadrootsOutboxEventState::DraftQueued.as_str()) .bind(input.created_at_ms) @@ -360,7 +360,7 @@ impl RadrootsOutbox { prepare_delivery_plan(input.draft.expected_event_id_str(), &input.delivery_plan)?; let operation_digest = operation_idempotency_digest( input.operation_kind.as_str(), - input.draft.expected_pubkey_str(), + &input.draft.expected_pubkey().to_hex(), &input.draft, ); let mut tx = self.pool.begin().await?; @@ -369,7 +369,7 @@ impl RadrootsOutbox { && let Some(existing) = existing_idempotent_operation( &mut tx, input.operation_kind.as_str(), - input.draft.expected_pubkey_str(), + &input.draft.expected_pubkey().to_hex(), idempotency_key, ) .await? @@ -377,7 +377,7 @@ impl RadrootsOutbox { if existing.operation_idempotency_digest != operation_digest { return Err(RadrootsOutboxError::IdempotencyConflict { operation_kind: input.operation_kind, - expected_pubkey: input.draft.expected_pubkey_str().to_owned(), + expected_pubkey: input.draft.expected_pubkey().to_hex().to_owned(), idempotency_key: idempotency_key.to_owned(), existing_digest: existing.operation_idempotency_digest, new_digest: operation_digest, @@ -416,7 +416,7 @@ impl RadrootsOutbox { "INSERT INTO outbox_operations(operation_kind, expected_pubkey, semantic_scope, trade_id, mutation_id, canonical_payload_sha256, idempotency_key, operation_idempotency_digest, status, created_at_ms, updated_at_ms) VALUES (?, ?, 'generic_event', NULL, NULL, NULL, ?, ?, ?, ?, ?)", ) .bind(input.operation_kind.as_str()) - .bind(input.draft.expected_pubkey_str()) + .bind(input.draft.expected_pubkey().to_hex()) .bind(input.idempotency_key.as_deref()) .bind(operation_digest.as_str()) .bind(RadrootsOutboxOperationStatus::Queued.as_str()) @@ -432,7 +432,7 @@ impl RadrootsOutbox { ) .bind(operation_id) .bind(input.draft.expected_event_id_str()) - .bind(input.draft.expected_pubkey_str()) + .bind(input.draft.expected_pubkey().to_hex()) .bind(draft_json.as_str()) .bind(signed_event_json.as_str()) .bind(input.signed_event.raw_json()) @@ -475,7 +475,7 @@ impl RadrootsOutbox { prepare_delivery_plan(input.draft.expected_event_id_str(), &input.delivery_plan)?; let operation_digest = trade_mutation_operation_idempotency_digest( input.operation_kind.as_str(), - input.draft.expected_pubkey_str(), + &input.draft.expected_pubkey().to_hex(), &semantic, ); let mut tx = self.pool.begin().await?; @@ -483,7 +483,7 @@ impl RadrootsOutbox { if let Some(existing) = existing_trade_mutation_operation( &mut tx, input.operation_kind.as_str(), - input.draft.expected_pubkey_str(), + &input.draft.expected_pubkey().to_hex(), input.mutation_id.as_str(), ) .await? @@ -491,7 +491,7 @@ impl RadrootsOutbox { if existing.operation_idempotency_digest != operation_digest { return Err(RadrootsOutboxError::IdempotencyConflict { operation_kind: input.operation_kind, - expected_pubkey: input.draft.expected_pubkey_str().to_owned(), + expected_pubkey: input.draft.expected_pubkey().to_hex().to_owned(), idempotency_key: input.mutation_id.to_string(), existing_digest: existing.operation_idempotency_digest, new_digest: operation_digest, @@ -524,7 +524,7 @@ impl RadrootsOutbox { && let Some(existing) = existing_idempotent_operation( &mut tx, input.operation_kind.as_str(), - input.draft.expected_pubkey_str(), + &input.draft.expected_pubkey().to_hex(), idempotency_key, ) .await? @@ -532,7 +532,7 @@ impl RadrootsOutbox { if existing.operation_idempotency_digest != operation_digest { return Err(RadrootsOutboxError::IdempotencyConflict { operation_kind: input.operation_kind, - expected_pubkey: input.draft.expected_pubkey_str().to_owned(), + expected_pubkey: input.draft.expected_pubkey().to_hex().to_owned(), idempotency_key: idempotency_key.to_owned(), existing_digest: existing.operation_idempotency_digest, new_digest: operation_digest, @@ -565,7 +565,7 @@ impl RadrootsOutbox { "INSERT INTO outbox_operations(operation_kind, expected_pubkey, semantic_scope, trade_id, mutation_id, canonical_payload_sha256, idempotency_key, operation_idempotency_digest, status, created_at_ms, updated_at_ms) VALUES (?, ?, 'trade_mutation', ?, ?, ?, ?, ?, ?, ?, ?)", ) .bind(input.operation_kind.as_str()) - .bind(input.draft.expected_pubkey_str()) + .bind(input.draft.expected_pubkey().to_hex()) .bind(input.trade_id.as_str()) .bind(input.mutation_id.as_str()) .bind(input.canonical_payload_sha256.as_str()) @@ -583,7 +583,7 @@ impl RadrootsOutbox { ) .bind(operation_id) .bind(input.draft.expected_event_id_str()) - .bind(input.draft.expected_pubkey_str()) + .bind(input.draft.expected_pubkey().to_hex()) .bind(draft_json.as_str()) .bind(RadrootsOutboxEventState::DraftQueued.as_str()) .bind(input.created_at_ms) @@ -622,7 +622,7 @@ impl RadrootsOutbox { prepare_delivery_plan(input.draft.expected_event_id_str(), &input.delivery_plan)?; let operation_digest = trade_mutation_operation_idempotency_digest( input.operation_kind.as_str(), - input.draft.expected_pubkey_str(), + &input.draft.expected_pubkey().to_hex(), &semantic, ); let mut tx = self.pool.begin().await?; @@ -630,7 +630,7 @@ impl RadrootsOutbox { if let Some(existing) = existing_trade_mutation_operation( &mut tx, input.operation_kind.as_str(), - input.draft.expected_pubkey_str(), + &input.draft.expected_pubkey().to_hex(), input.mutation_id.as_str(), ) .await? @@ -638,7 +638,7 @@ impl RadrootsOutbox { if existing.operation_idempotency_digest != operation_digest { return Err(RadrootsOutboxError::IdempotencyConflict { operation_kind: input.operation_kind, - expected_pubkey: input.draft.expected_pubkey_str().to_owned(), + expected_pubkey: input.draft.expected_pubkey().to_hex().to_owned(), idempotency_key: input.mutation_id.to_string(), existing_digest: existing.operation_idempotency_digest, new_digest: operation_digest, @@ -677,7 +677,7 @@ impl RadrootsOutbox { && let Some(existing) = existing_idempotent_operation( &mut tx, input.operation_kind.as_str(), - input.draft.expected_pubkey_str(), + &input.draft.expected_pubkey().to_hex(), idempotency_key, ) .await? @@ -685,7 +685,7 @@ impl RadrootsOutbox { if existing.operation_idempotency_digest != operation_digest { return Err(RadrootsOutboxError::IdempotencyConflict { operation_kind: input.operation_kind, - expected_pubkey: input.draft.expected_pubkey_str().to_owned(), + expected_pubkey: input.draft.expected_pubkey().to_hex().to_owned(), idempotency_key: idempotency_key.to_owned(), existing_digest: existing.operation_idempotency_digest, new_digest: operation_digest, @@ -724,7 +724,7 @@ impl RadrootsOutbox { "INSERT INTO outbox_operations(operation_kind, expected_pubkey, semantic_scope, trade_id, mutation_id, canonical_payload_sha256, idempotency_key, operation_idempotency_digest, status, created_at_ms, updated_at_ms) VALUES (?, ?, 'trade_mutation', ?, ?, ?, ?, ?, ?, ?, ?)", ) .bind(input.operation_kind.as_str()) - .bind(input.draft.expected_pubkey_str()) + .bind(input.draft.expected_pubkey().to_hex()) .bind(input.trade_id.as_str()) .bind(input.mutation_id.as_str()) .bind(input.canonical_payload_sha256.as_str()) @@ -743,7 +743,7 @@ impl RadrootsOutbox { ) .bind(operation_id) .bind(input.draft.expected_event_id_str()) - .bind(input.draft.expected_pubkey_str()) + .bind(input.draft.expected_pubkey().to_hex()) .bind(draft_json.as_str()) .bind(signed_event_json.as_str()) .bind(input.signed_event.raw_json()) @@ -783,7 +783,7 @@ impl RadrootsOutbox { prepare_delivery_plan(input.draft.expected_event_id_str(), &input.delivery_plan)?; let operation_digest = operation_idempotency_digest( input.operation_kind.as_str(), - input.draft.expected_pubkey_str(), + &input.draft.expected_pubkey().to_hex(), &input.draft, ); @@ -791,7 +791,7 @@ impl RadrootsOutbox { && let Some(existing) = existing_idempotent_operation( tx, input.operation_kind.as_str(), - input.draft.expected_pubkey_str(), + &input.draft.expected_pubkey().to_hex(), idempotency_key, ) .await? @@ -799,7 +799,7 @@ impl RadrootsOutbox { if existing.operation_idempotency_digest != operation_digest { return Err(RadrootsOutboxError::IdempotencyConflict { operation_kind: input.operation_kind, - expected_pubkey: input.draft.expected_pubkey_str().to_owned(), + expected_pubkey: input.draft.expected_pubkey().to_hex().to_owned(), idempotency_key: idempotency_key.to_owned(), existing_digest: existing.operation_idempotency_digest, new_digest: operation_digest, @@ -836,7 +836,7 @@ impl RadrootsOutbox { "INSERT INTO outbox_operations(operation_kind, expected_pubkey, semantic_scope, trade_id, mutation_id, canonical_payload_sha256, idempotency_key, operation_idempotency_digest, status, created_at_ms, updated_at_ms) VALUES (?, ?, 'generic_event', NULL, NULL, NULL, ?, ?, ?, ?, ?)", ) .bind(input.operation_kind.as_str()) - .bind(input.draft.expected_pubkey_str()) + .bind(input.draft.expected_pubkey().to_hex()) .bind(input.idempotency_key.as_deref()) .bind(operation_digest.as_str()) .bind(RadrootsOutboxOperationStatus::Queued.as_str()) @@ -852,7 +852,7 @@ impl RadrootsOutbox { ) .bind(operation_id) .bind(input.draft.expected_event_id_str()) - .bind(input.draft.expected_pubkey_str()) + .bind(input.draft.expected_pubkey().to_hex()) .bind(draft_json.as_str()) .bind(signed_event_json.as_str()) .bind(input.signed_event.raw_json()) @@ -3174,7 +3174,7 @@ fn validate_trade_mutation_input( } let parsed = trade_mutation_from_canonical_content(draft.content()) .map_err(|_| RadrootsOutboxError::TradeMutationMetadataMismatch { field: "content" })?; - if parsed.author_pubkey.as_str() != draft.expected_pubkey_str() { + if parsed.author_pubkey != *draft.expected_pubkey() { return Err(RadrootsOutboxError::TradeMutationMetadataMismatch { field: "author_pubkey", }); @@ -3396,7 +3396,7 @@ mod tests { use super::*; use radroots_event::ids::{ RadrootsClassifiedListingAddress, RadrootsDTag, RadrootsEventId, RadrootsInventoryBinId, - RadrootsPublicKey, RadrootsTradeId, + RadrootsTradeId, }; use radroots_event::kinds::{ KIND_CLASSIFIED_LISTING, KIND_FOLLOW, KIND_GEOCHAT, KIND_HTTP_AUTH, KIND_RELAY_AUTH, @@ -3409,6 +3409,7 @@ mod tests { RadrootsTradeEconomicsProfileV1, RadrootsTradeMutationBodyV1, RadrootsTradeMutationEnvelopeV1, canonical_jcs_value, canonical_trade_mutation_content, }; + use radroots_identity::PublicKey; use radroots_nostr::prelude::{ RadrootsNostrKeys, RadrootsNostrSecretKey, radroots_nostr_sign_frozen_draft, }; @@ -3417,6 +3418,8 @@ mod tests { "10c5304d6c9ae3a1a16f7860f1cc8f5e3a76225a2663b3a989a0d775919b7df5"; const FIXTURE_ALICE_PUBLIC_KEY_HEX: &str = "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df"; + const FIXTURE_BOB_PUBLIC_KEY_HEX: &str = + "e0266e3cfb0d2886f91c73f5f868f3b98273713e5fcd97c081663f5518a4b3af"; const NOSTR_PRIMARY_WSS: &str = "wss://relay.example.com"; const NOSTR_SECONDARY_WSS: &str = "wss://relay-2.example.com"; @@ -3428,11 +3431,13 @@ mod tests { std::iter::repeat_n(character, 32).collect() } - fn public_key(character: char) -> RadrootsPublicKey { - if character == 'a' { - return RadrootsPublicKey::parse(FIXTURE_ALICE_PUBLIC_KEY_HEX).expect("alice pubkey"); - } - RadrootsPublicKey::parse(hex_64(character)).expect("pubkey") + fn public_key(character: char) -> PublicKey { + let public_key_hex = match character { + 'a' => FIXTURE_ALICE_PUBLIC_KEY_HEX, + 'b' => FIXTURE_BOB_PUBLIC_KEY_HEX, + _ => panic!("unsupported fixture public key label: {character}"), + }; + PublicKey::from_hex(public_key_hex).expect("fixture pubkey") } fn generic_draft(expected_pubkey: &str, content: &str) -> RadrootsEventDraft { @@ -3567,7 +3572,7 @@ mod tests { canonical.envelope.authored_at_unix_s, tags, canonical.content.clone(), - canonical.envelope.author_pubkey.as_str(), + &canonical.envelope.author_pubkey.to_hex(), ) .expect("trade mutation draft") } @@ -3916,7 +3921,7 @@ mod tests { )); let author_mismatch = - proposal_draft_with_content(canonical.content.clone(), hex_64('b').as_str()); + proposal_draft_with_content(canonical.content.clone(), FIXTURE_BOB_PUBLIC_KEY_HEX); assert!(matches!( validate_trade_mutation_input( canonical.envelope.trade_id.as_str(), diff --git a/crates/replica_sync/src/ingest.rs b/crates/replica_sync/src/ingest.rs @@ -253,7 +253,7 @@ fn ingest_profile_event( ) -> Result<RadrootsReplicaIngestOutcome, RadrootsReplicaEventsError> { let data_result = profile_decode::data_from_event( event.id_str().to_owned(), - event.author_str().to_owned(), + event.author().to_hex().to_owned(), event.created_at_u64(), event.kind_u32(), event.content().to_owned(), @@ -355,7 +355,7 @@ fn ingest_farm_event( created_at: None, updated_at: None, d_tag: Some(farm.d_tag.clone()), - pubkey: Some(event.author_str().to_owned()), + pubkey: Some(event.author().to_hex().to_owned()), name: None, about: None, website: None, @@ -379,7 +379,7 @@ fn ingest_farm_event( let farm_id = if let Some(row) = existing.results.first() { let fields = IFarmFieldsPartial { d_tag: Some(Value::from(farm.d_tag.clone())), - pubkey: Some(Value::from(event.author_str().to_owned())), + pubkey: Some(Value::from(event.author().to_hex().to_owned())), name: Some(Value::from(farm.name.clone())), about: to_value_opt(farm.about.clone()), website: to_value_opt(farm.website.clone()), @@ -402,7 +402,7 @@ fn ingest_farm_event( } else { let fields = IFarmFields { d_tag: farm.d_tag.clone(), - pubkey: event.author_str().to_owned(), + pubkey: event.author().to_hex().to_owned(), name: farm.name.clone(), about: farm.about.clone(), website: farm.website.clone(), @@ -622,7 +622,7 @@ fn ingest_list_set_event( if !decision.apply { return Ok(RadrootsReplicaIngestOutcome::Skipped); } - upsert_member_claims(exec, event.author_str(), &list_set)?; + upsert_member_claims(exec, &event.author().to_hex(), &list_set)?; upsert_event_head(exec, &decision)?; return Ok(RadrootsReplicaIngestOutcome::Applied); } @@ -642,7 +642,7 @@ fn ingest_list_set_event( if !decision.apply { return Ok(RadrootsReplicaIngestOutcome::Skipped); } - let farm = find_farm_by_ref(exec, event.author_str(), &farm_d_tag)?; + let farm = find_farm_by_ref(exec, &event.author().to_hex(), &farm_d_tag)?; upsert_farm_members(exec, &farm.id, role, &list_set)?; upsert_event_head(exec, &decision)?; return Ok(RadrootsReplicaIngestOutcome::Applied); @@ -667,8 +667,9 @@ fn trade_product_fields_from_listing( listing_addr: &str, ) -> Result<ITradeProductFields, RadrootsReplicaEventsError> { let bin = primary_listing_bin(listing)?; - let qty_amt = decimal_to_f64(&bin.quantity.amount, "listing primary bin quantity")?; - let qty_amt_exact = bin.quantity.amount.to_string(); + let quantity_amount = bin.quantity.amount(); + let qty_amt = decimal_to_f64(&quantity_amount, "listing primary bin quantity")?; + let qty_amt_exact = quantity_amount.to_string(); let qty_avail = listing .inventory_available .as_ref() @@ -677,30 +678,30 @@ fn trade_product_fields_from_listing( let price_source = bin .display_price .as_ref() - .unwrap_or(&bin.price_per_canonical_unit.amount); - let Some(price_amt) = price_source.amount.to_f64_lossy() else { + .unwrap_or(bin.price_per_canonical_unit.amount()); + let Some(price_amt) = price_source.amount().to_f64_lossy() else { return Err(RadrootsReplicaEventsError::InvalidData( "listing price amount out of range".to_string(), )); }; - let price_amt_exact = price_source.amount.to_string(); - let price_currency = price_source.currency.as_str().to_string(); + let price_amt_exact = price_source.amount().to_string(); + let price_currency = price_source.currency().as_str().to_string(); let price_qty_amt = if bin.display_price.is_some() { 1.0 } else { decimal_to_f64( - &bin.price_per_canonical_unit.quantity.amount, + &bin.price_per_canonical_unit.quantity().amount(), "listing price quantity", )? }; let price_qty_amt_exact = if bin.display_price.is_some() { "1".to_string() } else { - bin.price_per_canonical_unit.quantity.amount.to_string() + bin.price_per_canonical_unit.quantity().amount().to_string() }; let price_qty_unit = bin .display_price_unit - .unwrap_or(bin.price_per_canonical_unit.quantity.unit) + .unwrap_or(bin.price_per_canonical_unit.quantity().unit()) .to_string(); Ok(ITradeProductFields { @@ -719,11 +720,11 @@ fn trade_product_fields_from_listing( .unwrap_or_default(), qty_amt, qty_amt_exact, - qty_unit: bin.quantity.unit.to_string(), + qty_unit: bin.quantity.unit().to_string(), qty_label: bin .display_label .clone() - .or_else(|| bin.quantity.label.clone()), + .or_else(|| bin.quantity.label().map(ToOwned::to_owned)), qty_avail, price_amt, price_amt_exact, @@ -1019,7 +1020,7 @@ fn event_head_decision( apply: false, key: String::new(), kind: event.kind_u32(), - pubkey: event.author_str().to_owned(), + pubkey: event.author().to_hex().to_owned(), d_tag: String::new(), last_event_id: event.id_str().to_owned(), last_created_at: event.created_at_u64(), @@ -1683,7 +1684,7 @@ mod tests { ) -> RadrootsEventEnvelope { RadrootsEventEnvelope::new(RadrootsEventEnvelopeParts { id: event.id_str().to_owned(), - author: event.author_str().to_owned(), + author: event.author().to_hex().to_owned(), created_at: event.created_at_u64(), kind, tags, diff --git a/crates/trade/Cargo.toml b/crates/trade/Cargo.toml @@ -30,6 +30,7 @@ std = [ "radroots_event/std", "radroots_event_codec/std", "radroots_event_codec/nostr", + "radroots_identity/std", ] event_store = [ "std", @@ -45,6 +46,7 @@ serde = [ "radroots_core/serde", "radroots_event/serde", "radroots_event_codec/serde", + "radroots_identity/serde", ] serde_json = [ "serde", @@ -60,6 +62,7 @@ radroots_authority = { workspace = true, default-features = false } radroots_core = { workspace = true, default-features = false } radroots_event = { workspace = true, default-features = false } radroots_event_codec = { workspace = true, default-features = false } +radroots_identity = { workspace = true, default-features = false } radroots_event_store = { workspace = true, optional = true, default-features = false } base64 = { workspace = true, optional = true } dto_bindgen = { workspace = true, optional = true } diff --git a/crates/trade/src/identity.rs b/crates/trade/src/identity.rs @@ -4,8 +4,8 @@ use core::str::FromStr; use radroots_event::ids::{ RadrootsClassifiedListingAddress, RadrootsEventId, RadrootsIdParseError, RadrootsOrderId, - RadrootsPublicKey, }; +use radroots_identity::PublicKey; #[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "dto-bindgen", dto(as = "string"))] @@ -66,8 +66,10 @@ pub struct RadrootsTradeLocator { pub trade_id: RadrootsTradeId, pub root_event_id: Option<RadrootsEventId>, pub listing_addr: Option<RadrootsClassifiedListingAddress>, - pub buyer_pubkey: Option<RadrootsPublicKey>, - pub seller_pubkey: Option<RadrootsPublicKey>, + #[cfg_attr(feature = "dto-bindgen", dto(as = "string"))] + pub buyer_pubkey: Option<PublicKey>, + #[cfg_attr(feature = "dto-bindgen", dto(as = "string"))] + pub seller_pubkey: Option<PublicKey>, } impl RadrootsTradeLocator { @@ -99,12 +101,12 @@ impl RadrootsTradeLocator { self } - pub fn with_buyer_pubkey(mut self, buyer_pubkey: RadrootsPublicKey) -> Self { + pub fn with_buyer_pubkey(mut self, buyer_pubkey: PublicKey) -> Self { self.buyer_pubkey = Some(buyer_pubkey); self } - pub fn with_seller_pubkey(mut self, seller_pubkey: RadrootsPublicKey) -> Self { + pub fn with_seller_pubkey(mut self, seller_pubkey: PublicKey) -> Self { self.seller_pubkey = Some(seller_pubkey); self } @@ -118,8 +120,10 @@ pub struct RadrootsTradeLocatorCandidate { pub trade_id: RadrootsTradeId, pub root_event_id: RadrootsEventId, pub listing_addr: RadrootsClassifiedListingAddress, - pub buyer_pubkey: RadrootsPublicKey, - pub seller_pubkey: RadrootsPublicKey, + #[cfg_attr(feature = "dto-bindgen", dto(as = "string"))] + pub buyer_pubkey: PublicKey, + #[cfg_attr(feature = "dto-bindgen", dto(as = "string"))] + pub seller_pubkey: PublicKey, } impl RadrootsTradeLocatorCandidate { @@ -138,9 +142,10 @@ impl RadrootsTradeLocatorCandidate { mod tests { use super::*; use radroots_event::kinds::KIND_CLASSIFIED_LISTING; + use radroots_test_fixtures::{FIXTURE_ALICE_PUBLIC_KEY_HEX, FIXTURE_BOB_PUBLIC_KEY_HEX}; - const BUYER: &str = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; - const SELLER: &str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + const BUYER: &str = FIXTURE_BOB_PUBLIC_KEY_HEX; + const SELLER: &str = FIXTURE_ALICE_PUBLIC_KEY_HEX; fn event_id(raw: u8) -> RadrootsEventId { RadrootsEventId::parse(format!("{raw:064x}")).expect("event id") @@ -150,8 +155,8 @@ mod tests { RadrootsOrderId::parse("order-1").expect("order id") } - fn public_key(raw: &str) -> RadrootsPublicKey { - RadrootsPublicKey::parse(raw).expect("public key") + fn public_key(raw: &str) -> PublicKey { + PublicKey::from_hex(raw).expect("public key") } fn listing_addr() -> RadrootsClassifiedListingAddress { diff --git a/crates/trade/src/operational_listing/draft.rs b/crates/trade/src/operational_listing/draft.rs @@ -8,19 +8,17 @@ use core::fmt; use alloc::{format, string::ToString, vec::Vec}; #[cfg(feature = "std")] -use std::{string::ToString, vec::Vec}; +use std::vec::Vec; use radroots_authority::RadrootsActorContext; use radroots_event::{ contract::RadrootsActorRole, - ids::{ - RadrootsClassifiedListingAddress, RadrootsIdParseError, RadrootsInventoryBinId, - RadrootsPublicKey, - }, + ids::{RadrootsClassifiedListingAddress, RadrootsIdParseError, RadrootsInventoryBinId}, kinds::KIND_CLASSIFIED_LISTING, operational_listing::RadrootsOperationalListing, trade_validation::RadrootsOperationalListingValidationError, }; +use radroots_identity::{Error as PublicKeyError, PublicKey}; use super::validation::validate_operational_listing_model; @@ -40,16 +38,16 @@ impl RadrootsOperationalListingEditDocumentV1 { #[derive(Clone, Debug)] pub struct RadrootsOperationalListingCanonicalEdit { listing: RadrootsOperationalListing, - seller_pubkey: RadrootsPublicKey, + seller_pubkey: PublicKey, public_listing_addr: RadrootsClassifiedListingAddress, } impl RadrootsOperationalListingCanonicalEdit { pub fn new( mut listing: RadrootsOperationalListing, - seller_pubkey: RadrootsPublicKey, + seller_pubkey: PublicKey, ) -> Result<Self, RadrootsOperationalListingEditError> { - let farm_pubkey = RadrootsPublicKey::parse(listing.farm.pubkey.as_str()) + let farm_pubkey = PublicKey::from_hex(listing.farm.pubkey.as_str()) .map_err(RadrootsOperationalListingEditError::InvalidFarmPubkey)?; if farm_pubkey != seller_pubkey { return Err(RadrootsOperationalListingEditError::FarmPubkeyMismatch { @@ -57,7 +55,7 @@ impl RadrootsOperationalListingCanonicalEdit { actual_pubkey: farm_pubkey, }); } - listing.farm.pubkey = farm_pubkey.as_str().to_string(); + listing.farm.pubkey = farm_pubkey.to_hex(); validate_listing_bins(&listing)?; let listing = validate_operational_listing_model(listing, &seller_pubkey) .map_err(RadrootsOperationalListingEditError::InvalidModel)? @@ -80,7 +78,7 @@ impl RadrootsOperationalListingCanonicalEdit { &self.listing } - pub fn seller_pubkey(&self) -> &RadrootsPublicKey { + pub fn seller_pubkey(&self) -> &PublicKey { &self.seller_pubkey } @@ -91,15 +89,15 @@ impl RadrootsOperationalListingCanonicalEdit { #[derive(Clone, Debug, PartialEq, Eq)] pub enum RadrootsOperationalListingEditError { - InvalidFarmPubkey(RadrootsIdParseError), + InvalidFarmPubkey(PublicKeyError), InvalidClassifiedListingAddress(RadrootsIdParseError), InvalidModel(RadrootsOperationalListingValidationError), ActorRoleUnsatisfied { required_role: RadrootsActorRole, }, FarmPubkeyMismatch { - expected_pubkey: RadrootsPublicKey, - actual_pubkey: RadrootsPublicKey, + expected_pubkey: PublicKey, + actual_pubkey: PublicKey, }, MissingPrimaryBin { primary_bin_id: RadrootsInventoryBinId, @@ -165,10 +163,10 @@ fn validate_listing_bins( fn listing_addr( kind: u32, - seller_pubkey: &RadrootsPublicKey, + seller_pubkey: &PublicKey, d_tag: &str, ) -> RadrootsClassifiedListingAddress { - RadrootsClassifiedListingAddress::parse(format!("{kind}:{}:{d_tag}", seller_pubkey.as_str())) + RadrootsClassifiedListingAddress::parse(format!("{kind}:{seller_pubkey}:{d_tag}")) .expect("typed listing identity must form a listing address") } @@ -185,7 +183,7 @@ pub fn canonicalize_operational_listing_edit( let seller_pubkey = actor.pubkey().clone(); let farm_pubkey = document.listing.farm.pubkey.as_str(); if farm_pubkey.is_empty() { - document.listing.farm.pubkey = seller_pubkey.as_str().to_string(); + document.listing.farm.pubkey = seller_pubkey.to_hex(); } RadrootsOperationalListingCanonicalEdit::new(document.listing, seller_pubkey) @@ -198,10 +196,7 @@ mod tests { use radroots_event::{ contract::RadrootsActorRole, farm::RadrootsFarmRef, - ids::{ - RadrootsClassifiedListingAddress, RadrootsDTag, RadrootsInventoryBinId, - RadrootsPublicKey, - }, + ids::{RadrootsClassifiedListingAddress, RadrootsDTag, RadrootsInventoryBinId}, kinds::KIND_CLASSIFIED_LISTING, operational_listing::{ RadrootsOperationalListing, RadrootsOperationalListingAvailability, @@ -211,14 +206,16 @@ mod tests { }, trade_validation::RadrootsOperationalListingValidationError, }; + use radroots_identity::PublicKey; + use radroots_test_fixtures::{FIXTURE_ALICE_PUBLIC_KEY_HEX, FIXTURE_BOB_PUBLIC_KEY_HEX}; use super::{ RadrootsOperationalListingCanonicalEdit, RadrootsOperationalListingEditDocumentV1, RadrootsOperationalListingEditError, canonicalize_operational_listing_edit, }; - const SELLER: &str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; - const OTHER: &str = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; + const SELLER: &str = FIXTURE_ALICE_PUBLIC_KEY_HEX; + const OTHER: &str = FIXTURE_BOB_PUBLIC_KEY_HEX; fn d_tag(raw: &str) -> RadrootsDTag { RadrootsDTag::parse(raw).expect("d tag") @@ -308,13 +305,13 @@ mod tests { let canonical = canonicalize_operational_listing_edit(&seller_actor(), document) .expect("canonical draft"); - assert_eq!(canonical.seller_pubkey().as_str(), SELLER); + assert_eq!(canonical.seller_pubkey().to_hex(), SELLER); assert_eq!(canonical.listing().product.title, "Coffee"); } #[test] fn canonical_draft_carries_seller_listing_and_addresses() { - let seller_pubkey = RadrootsPublicKey::parse(SELLER).expect("seller"); + let seller_pubkey = PublicKey::from_hex(SELLER).expect("seller"); let listing = listing(); let canonical = @@ -333,7 +330,7 @@ mod tests { fn listing_edit_error_variants_are_precise() { assert!(matches!( RadrootsOperationalListingEditError::InvalidFarmPubkey( - RadrootsPublicKey::parse("bad").unwrap_err() + PublicKey::from_hex("bad").unwrap_err() ), RadrootsOperationalListingEditError::InvalidFarmPubkey(_) )); @@ -354,7 +351,7 @@ mod tests { let canonical = canonicalize_operational_listing_edit(&seller_actor(), document) .expect("canonical draft"); - assert_eq!(canonical.seller_pubkey().as_str(), SELLER); + assert_eq!(canonical.seller_pubkey().to_hex(), SELLER); assert_eq!( canonical.public_listing_addr().as_str(), format!("{KIND_CLASSIFIED_LISTING}:{SELLER}:AAAAAAAAAAAAAAAAAAAAAg") @@ -411,7 +408,7 @@ mod tests { let error = RadrootsOperationalListingCanonicalEdit::new( listing, - RadrootsPublicKey::parse(SELLER).expect("seller"), + PublicKey::from_hex(SELLER).expect("seller"), ) .unwrap_err(); @@ -428,7 +425,7 @@ mod tests { let error = RadrootsOperationalListingCanonicalEdit::new( listing, - RadrootsPublicKey::parse(SELLER).expect("seller"), + PublicKey::from_hex(SELLER).expect("seller"), ) .unwrap_err(); @@ -445,7 +442,7 @@ mod tests { let error = RadrootsOperationalListingCanonicalEdit::new( listing, - RadrootsPublicKey::parse(SELLER).expect("seller"), + PublicKey::from_hex(SELLER).expect("seller"), ) .unwrap_err(); @@ -478,7 +475,7 @@ mod tests { let error = RadrootsOperationalListingCanonicalEdit::new( listing, - RadrootsPublicKey::parse(SELLER).expect("seller"), + PublicKey::from_hex(SELLER).expect("seller"), ) .unwrap_err(); @@ -513,7 +510,7 @@ mod tests { let error = RadrootsOperationalListingCanonicalEdit::new( listing, - RadrootsPublicKey::parse(SELLER).expect("seller"), + PublicKey::from_hex(SELLER).expect("seller"), ) .unwrap_err(); @@ -535,7 +532,7 @@ mod tests { let error = RadrootsOperationalListingCanonicalEdit::new( invalid_quantity_listing, - RadrootsPublicKey::parse(SELLER).expect("seller"), + PublicKey::from_hex(SELLER).expect("seller"), ) .unwrap_err(); @@ -558,7 +555,7 @@ mod tests { let error = RadrootsOperationalListingCanonicalEdit::new( mismatched_unit_listing, - RadrootsPublicKey::parse(SELLER).expect("seller"), + PublicKey::from_hex(SELLER).expect("seller"), ) .unwrap_err(); @@ -577,7 +574,7 @@ mod tests { let error = RadrootsOperationalListingCanonicalEdit::new( listing, - RadrootsPublicKey::parse(SELLER).expect("seller"), + PublicKey::from_hex(SELLER).expect("seller"), ) .unwrap_err(); diff --git a/crates/trade/src/operational_listing/mod.rs b/crates/trade/src/operational_listing/mod.rs @@ -8,11 +8,12 @@ use radroots_event::{ RadrootsEventEnvelope, ids::{ RadrootsAddressableCoordinateParts, RadrootsClassifiedListingAddress, RadrootsDTag, - RadrootsIdParseError, RadrootsPublicKey, + RadrootsIdParseError, }, operational_listing::{RadrootsOperationalListing, RadrootsOperationalListingParseError}, }; use radroots_event_codec::operational_listing::decode::operational_listing_from_nostr_event; +use radroots_identity::PublicKey; pub use self::draft::{ RadrootsOperationalListingCanonicalEdit, RadrootsOperationalListingEditDocumentV1, @@ -32,7 +33,7 @@ pub use self::validation::{ pub struct RadrootsClassifiedListingAddressParts { pub address: RadrootsClassifiedListingAddress, pub kind: u32, - pub seller_pubkey: RadrootsPublicKey, + pub seller_pubkey: PublicKey, pub listing_id: RadrootsDTag, } @@ -46,7 +47,7 @@ impl RadrootsClassifiedListingAddressParts { pub struct RadrootsPublicClassifiedListingAddress { pub address: RadrootsClassifiedListingAddress, pub kind: u32, - pub seller_pubkey: RadrootsPublicKey, + pub seller_pubkey: PublicKey, pub listing_id: RadrootsDTag, } @@ -186,9 +187,9 @@ mod tests { assert_eq!(listing.address.as_str(), raw); assert_eq!(public.address.as_str(), raw); assert_eq!(typed.address.as_str(), raw); - assert_eq!(listing.seller_pubkey.as_str(), SELLER); - assert_eq!(public.seller_pubkey.as_str(), SELLER); - assert_eq!(typed.seller_pubkey.as_str(), SELLER); + assert_eq!(listing.seller_pubkey.to_hex(), SELLER); + assert_eq!(public.seller_pubkey.to_hex(), SELLER); + assert_eq!(typed.seller_pubkey.to_hex(), SELLER); } #[test] @@ -198,7 +199,7 @@ mod tests { assert_eq!(parsed.address.as_str(), raw); assert_eq!(parsed.kind, KIND_CLASSIFIED_LISTING); - assert_eq!(parsed.seller_pubkey.as_str(), SELLER); + assert_eq!(parsed.seller_pubkey.to_hex(), SELLER); assert_eq!(parsed.listing_id.as_str(), "listing-1"); } diff --git a/crates/trade/src/operational_listing/mutation.rs b/crates/trade/src/operational_listing/mutation.rs @@ -162,7 +162,7 @@ pub fn build_operational_listing_mutation_draft( created_at, parts.tags, parts.content, - draft.seller_pubkey().as_str(), + &draft.seller_pubkey().to_hex(), ) .map_err(RadrootsOperationalListingMutationError::FrozenDraft) } @@ -173,10 +173,7 @@ mod tests { use radroots_event::{ contract::validate_event_contract_shape, farm::RadrootsFarmRef, - ids::{ - RadrootsClassifiedListingAddress, RadrootsDTag, RadrootsInventoryBinId, - RadrootsPublicKey, - }, + ids::{RadrootsClassifiedListingAddress, RadrootsDTag, RadrootsInventoryBinId}, kinds::KIND_CLASSIFIED_LISTING, operational_listing::{ RadrootsOperationalListing, RadrootsOperationalListingAvailability, @@ -187,6 +184,7 @@ mod tests { resource_area::RadrootsResourceAreaRef, }; use radroots_event_codec::verification::verify_nip01_event; + use radroots_identity::PublicKey; use radroots_nostr::prelude::{ RadrootsNostrKeys, RadrootsNostrSecretKey, radroots_nostr_sign_frozen_draft, }; @@ -267,7 +265,7 @@ mod tests { fn canonical_draft() -> RadrootsOperationalListingCanonicalEdit { RadrootsOperationalListingCanonicalEdit::new( listing(), - RadrootsPublicKey::parse(SELLER).expect("seller"), + PublicKey::from_hex(SELLER).expect("seller"), ) .expect("canonical listing edit") } @@ -305,7 +303,7 @@ mod tests { .canonical_draft() .expect("draft") .seller_pubkey() - .as_str(), + .to_hex(), SELLER ); assert_eq!( @@ -313,7 +311,7 @@ mod tests { .canonical_draft() .expect("draft") .seller_pubkey() - .as_str(), + .to_hex(), SELLER ); assert_eq!( @@ -321,7 +319,7 @@ mod tests { .canonical_draft() .expect("draft") .seller_pubkey() - .as_str(), + .to_hex(), SELLER ); assert_eq!( @@ -393,7 +391,7 @@ mod tests { publish_draft.contract_id(), OPERATIONAL_LISTING_PUBLISHED_CONTRACT_ID ); - assert_eq!(publish_draft.expected_pubkey_str(), SELLER); + assert_eq!(publish_draft.expected_pubkey().to_hex(), SELLER); assert_eq!(publish_draft.created_at_u64(), 1_700_000_000); assert_eq!(publish_draft.content(), "# Coffee\n\nSingle origin coffee"); assert_eq!(update_draft.kind_u32(), KIND_CLASSIFIED_LISTING); @@ -401,7 +399,7 @@ mod tests { update_draft.contract_id(), OPERATIONAL_LISTING_PUBLISHED_CONTRACT_ID ); - assert_eq!(update_draft.expected_pubkey_str(), SELLER); + assert_eq!(update_draft.expected_pubkey().to_hex(), SELLER); } #[test] @@ -438,7 +436,7 @@ mod tests { }); let draft = RadrootsOperationalListingCanonicalEdit::new( listing, - RadrootsPublicKey::parse(SELLER).expect("seller"), + PublicKey::from_hex(SELLER).expect("seller"), ) .expect("canonical listing edit"); let publish = RadrootsOperationalListingMutation::publish(draft); diff --git a/crates/trade/src/operational_listing/validation.rs b/crates/trade/src/operational_listing/validation.rs @@ -9,7 +9,7 @@ use alloc::{ use radroots_core::{Decimal, Money, Quantity, Unit}; use radroots_event::{ classified_listing::{RadrootsClassifiedListingPartition, classify_classified_listing_tags}, - ids::{RadrootsClassifiedListingAddress, RadrootsPublicKey}, + ids::RadrootsClassifiedListingAddress, kinds::{KIND_CLASSIFIED_LISTING, is_classified_listing_kind}, location::{has_textual_locality, is_public_geohash5}, operational_listing::{ @@ -19,6 +19,7 @@ use radroots_event::{ }, trade_validation::RadrootsOperationalListingValidationError as OperationalListingValidationError, }; +use radroots_identity::PublicKey; use radroots_event_codec::{ operational_listing::decode::operational_listing_from_nostr_event, @@ -86,17 +87,14 @@ pub fn validate_operational_listing_event( /// [`validate_operational_listing_event`] instead. pub fn validate_operational_listing_model( listing: RadrootsOperationalListing, - seller_pubkey: &RadrootsPublicKey, + seller_pubkey: &PublicKey, ) -> Result<RadrootsOperationalListingTradeProjection, OperationalListingValidationError> { let listing_id = listing.d_tag.trim().to_string(); - if listing.farm.pubkey != seller_pubkey.as_str() { + if listing.farm.pubkey != seller_pubkey.to_hex() { return Err(OperationalListingValidationError::InvalidSeller); } - let listing_addr_raw = format!( - "{KIND_CLASSIFIED_LISTING}:{}:{listing_id}", - seller_pubkey.as_str() - ); + let listing_addr_raw = format!("{KIND_CLASSIFIED_LISTING}:{}:{listing_id}", seller_pubkey); let listing_addr = RadrootsClassifiedListingAddress::parse(&listing_addr_raw) .expect("validated listing identity must form a listing address"); @@ -182,7 +180,7 @@ pub fn validate_operational_listing_model( Ok(RadrootsOperationalListingTradeProjection { listing_id, listing_addr, - seller_pubkey: seller_pubkey.as_str().to_string(), + seller_pubkey: seller_pubkey.to_hex(), title, description, product_type, @@ -241,7 +239,7 @@ mod tests { use radroots_event::{ RadrootsEventEnvelope, RadrootsEventEnvelopeParts, farm::RadrootsFarmRef, - ids::{RadrootsDTag, RadrootsInventoryBinId, RadrootsPublicKey}, + ids::{RadrootsDTag, RadrootsInventoryBinId}, kinds::KIND_CLASSIFIED_LISTING, operational_listing::{ RadrootsOperationalListing, RadrootsOperationalListingAvailability, @@ -250,6 +248,7 @@ mod tests { }, }; use radroots_event_codec::verification::{RadrootsSignatureVerifiedEvent, verify_nip01_event}; + use radroots_identity::PublicKey; use radroots_nostr::prelude::radroots_event_from_nostr; use radroots_test_fixtures::{ FIXTURE_ALICE_PUBLIC_KEY_HEX, FIXTURE_ALICE_SECRET_KEY_HEX, FIXTURE_BOB_PUBLIC_KEY_HEX, @@ -267,12 +266,12 @@ mod tests { RadrootsInventoryBinId::parse(raw).expect("bin id") } - fn seller_pubkey() -> RadrootsPublicKey { - RadrootsPublicKey::parse(SELLER).expect("seller pubkey") + fn seller_pubkey() -> PublicKey { + PublicKey::from_hex(SELLER).expect("seller pubkey") } - fn other_seller_pubkey() -> RadrootsPublicKey { - RadrootsPublicKey::parse(OTHER_SELLER).expect("other seller pubkey") + fn other_seller_pubkey() -> PublicKey { + PublicKey::from_hex(OTHER_SELLER).expect("other seller pubkey") } fn base_listing() -> RadrootsOperationalListing { @@ -738,7 +737,7 @@ mod tests { let event = verified.into_event(); let tampered = RadrootsEventEnvelope::new(RadrootsEventEnvelopeParts { id: event.id_str().to_owned(), - author: event.author_str().to_owned(), + author: event.author().to_hex().to_owned(), created_at: event.created_at_u64(), kind: event.kind_u32(), tags: event.tags_as_vec(), diff --git a/crates/trade/src/validation_receipt.rs b/crates/trade/src/validation_receipt.rs @@ -10,11 +10,12 @@ use alloc::{ use base64::Engine as _; use radroots_event::{ RadrootsEventEnvelope, - ids::{RadrootsAddressableCoordinate, RadrootsAddressableCoordinateParts, RadrootsPublicKey}, + ids::{RadrootsAddressableCoordinate, RadrootsAddressableCoordinateParts}, kinds::{KIND_TRADE_VALIDATION_RECEIPT, KIND_VALIDATOR_SET}, tags::{TAG_A, TAG_D}, wire::RadrootsNip01EventWireParts, }; +use radroots_identity::PublicKey; use serde::{Deserialize, Serialize}; use sha2::{Digest, Sha256}; use thiserror::Error; @@ -38,7 +39,7 @@ pub const VALIDATOR_SET_V1_THRESHOLD: u8 = 1; #[serde(deny_unknown_fields)] pub struct RadrootsValidatorSetV1 { pub set_id: String, - pub validator_pubkey: RadrootsPublicKey, + pub validator_pubkey: PublicKey, pub threshold: u8, pub valid_from: u64, pub valid_until: u64, @@ -52,7 +53,7 @@ pub struct RadrootsVerifiedValidatorSetV1 { pub set: RadrootsValidatorSetV1, pub event_id: String, pub address: RadrootsAddressableCoordinate, - pub authority_pubkey: RadrootsPublicKey, + pub authority_pubkey: PublicKey, } #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] @@ -204,7 +205,7 @@ impl RadrootsTradeValidationTrustPolicy { self } - pub fn trusts_validator_pubkey(&self, pubkey: &RadrootsPublicKey) -> bool { + pub fn trusts_validator_pubkey(&self, pubkey: &PublicKey) -> bool { self.validator_set .as_ref() .is_some_and(|validator_set| validator_set.validator_pubkey == *pubkey) @@ -426,7 +427,7 @@ impl RadrootsValidatorSetV1 { } pub fn validator_set_address( - authority_pubkey: &RadrootsPublicKey, + authority_pubkey: &PublicKey, set_id: &str, ) -> Result<RadrootsAddressableCoordinate, RadrootsValidationReceiptError> { validate_uuidv7(set_id, "validator_set.set_id")?; @@ -484,7 +485,7 @@ pub fn validator_set_from_event( pub fn verify_validator_set_event( event: &RadrootsEventEnvelope, - expected_author: Option<&RadrootsPublicKey>, + expected_author: Option<&PublicKey>, ) -> Result<RadrootsVerifiedValidatorSetV1, RadrootsValidationReceiptError> { if event.kind_u32() != KIND_VALIDATOR_SET { return Err(RadrootsValidationReceiptError::InvalidKind { @@ -1146,10 +1147,14 @@ mod tests { }; use radroots_event::{ RadrootsEventEnvelope, RadrootsEventEnvelopeParts, - ids::{RadrootsAddressableCoordinate, RadrootsPublicKey}, + ids::RadrootsAddressableCoordinate, kinds::{KIND_TRADE_VALIDATION_RECEIPT, KIND_VALIDATOR_SET}, tags::TAG_D, }; + use radroots_identity::PublicKey; + use radroots_test_fixtures::{ + FIXTURE_BOB_PUBLIC_KEY_HEX, FIXTURE_CAROL_PUBLIC_KEY_HEX, FIXTURE_DIEGO_PUBLIC_KEY_HEX, + }; fn hash32(c: char) -> String { format!("0x{}", c.to_string().repeat(64)) @@ -1163,12 +1168,12 @@ mod tests { "018f3d99-7d35-7c0c-8a0f-7f3b645abcde".to_string() } - fn validator_set_author() -> RadrootsPublicKey { - RadrootsPublicKey::parse(event_id('d')).expect("validator set author") + fn validator_set_author() -> PublicKey { + PublicKey::from_hex(FIXTURE_DIEGO_PUBLIC_KEY_HEX).expect("validator set author") } - fn validator_set_pubkey() -> RadrootsPublicKey { - RadrootsPublicKey::parse(event_id('e')).expect("validator pubkey") + fn validator_set_pubkey() -> PublicKey { + PublicKey::from_hex(FIXTURE_CAROL_PUBLIC_KEY_HEX).expect("validator pubkey") } fn validator_set_addr() -> radroots_event::ids::RadrootsAddressableCoordinate { @@ -1271,7 +1276,7 @@ mod tests { ) -> RadrootsEventEnvelope { RadrootsEventEnvelope::new(RadrootsEventEnvelopeParts { id: event_id('7'), - author: validator_set_author().as_str().to_string(), + author: validator_set_author().to_hex(), created_at: 1_700_000_001, kind, tags, @@ -1383,7 +1388,7 @@ mod tests { #[test] fn validation_trust_policy_builders_preserve_explicit_settings() { let trusted = validator_set_pubkey(); - let other = RadrootsPublicKey::parse(event_id('b')).unwrap(); + let other = PublicKey::from_hex(FIXTURE_BOB_PUBLIC_KEY_HEX).expect("other validator"); let policy = RadrootsTradeValidationTrustPolicy::production() .with_validator_set(sample_validator_set(), validator_set_addr(), event_id('8')) .with_require_cryptographic_proof(false); @@ -1422,7 +1427,7 @@ mod tests { let event = RadrootsEventEnvelope::new(RadrootsEventEnvelopeParts { id: event_id('7'), - author: validator_set_author().as_str().to_string(), + author: validator_set_author().to_hex(), created_at: 1_700_000_001, kind: parts.kind, tags: parts.tags, diff --git a/crates/trade/src/workflow.rs b/crates/trade/src/workflow.rs @@ -15,8 +15,8 @@ use std::{ use radroots_event::{ ids::{ - RadrootsDTag, RadrootsEventId, RadrootsPublicKey, RadrootsTradeCandidateId, - RadrootsTradeId, RadrootsTradeMutationId, + RadrootsDTag, RadrootsEventId, RadrootsTradeCandidateId, RadrootsTradeId, + RadrootsTradeMutationId, }, trade::{ RADROOTS_TRADE_SCHEMA_VERSION, RadrootsSellerReservationAssertionV1, @@ -24,6 +24,7 @@ use radroots_event::{ RadrootsTradeMutationEnvelopeV1, }, }; +use radroots_identity::PublicKey; #[cfg(feature = "serde_json")] use sha2::{Digest, Sha256}; @@ -202,8 +203,10 @@ pub struct RadrootsTradeProjectionV1 { pub reducer_version: u16, pub trade_id: RadrootsTradeId, pub root_mutation_id: Option<RadrootsTradeMutationId>, - pub buyer_pubkey: Option<RadrootsPublicKey>, - pub seller_pubkey: Option<RadrootsPublicKey>, + #[cfg_attr(feature = "dto-bindgen", dto(as = "string"))] + pub buyer_pubkey: Option<PublicKey>, + #[cfg_attr(feature = "dto-bindgen", dto(as = "string"))] + pub seller_pubkey: Option<PublicKey>, pub farm_id: Option<RadrootsDTag>, pub negotiation_state: RadrootsTradeNegotiationStateV1, pub agreement_state: RadrootsTradeAgreementStateV1, @@ -295,8 +298,10 @@ pub struct RadrootsTradeAgreementClaimV1 { pub claim_mutation_id: RadrootsTradeMutationId, pub proposal_mutation_id: RadrootsTradeMutationId, pub candidate_id: RadrootsTradeCandidateId, - pub candidate_author_pubkey: RadrootsPublicKey, - pub accepted_by_pubkey: RadrootsPublicKey, + #[cfg_attr(feature = "dto-bindgen", dto(as = "string"))] + pub candidate_author_pubkey: PublicKey, + #[cfg_attr(feature = "dto-bindgen", dto(as = "string"))] + pub accepted_by_pubkey: PublicKey, pub reservation_commitment: String, } @@ -373,7 +378,7 @@ pub enum RadrootsTradeReducerIssueV1 { #[derive(Clone, Debug, PartialEq, Eq)] struct CandidateRecord { proposal_mutation_id: RadrootsTradeMutationId, - author_pubkey: RadrootsPublicKey, + author_pubkey: PublicKey, candidate: RadrootsTradeCandidateTermsV1, } @@ -723,7 +728,7 @@ fn apply_decision( fn candidate_record_author_counterparty( candidate_record: &CandidateRecord, mutation: &RadrootsTradeMutationEnvelopeV1, -) -> RadrootsPublicKey { +) -> PublicKey { if candidate_record.author_pubkey == mutation.buyer_pubkey { mutation.seller_pubkey.clone() } else { @@ -1086,6 +1091,7 @@ mod tests { RadrootsTradePrivateTermsRefV1, canonical_trade_mutation_content, }, }; + use radroots_test_fixtures::{FIXTURE_ALICE_PUBLIC_KEY_HEX, FIXTURE_BOB_PUBLIC_KEY_HEX}; fn hex_64(character: char) -> String { core::iter::repeat_n(character, 64).collect() @@ -1095,8 +1101,13 @@ mod tests { core::iter::repeat_n(character, 32).collect() } - fn pubkey(character: char) -> RadrootsPublicKey { - RadrootsPublicKey::parse(hex_64(character)).unwrap() + fn pubkey(character: char) -> PublicKey { + let public_key_hex = match character { + 'a' => FIXTURE_ALICE_PUBLIC_KEY_HEX, + 'b' => FIXTURE_BOB_PUBLIC_KEY_HEX, + _ => panic!("unsupported fixture public key label: {character}"), + }; + PublicKey::from_hex(public_key_hex).expect("fixture pubkey") } fn event_id(character: char) -> RadrootsEventId { @@ -1128,7 +1139,7 @@ mod tests { line_id: dtag(&format!("line-{line_suffix}")), listing_addr: RadrootsClassifiedListingAddress::parse(format!( "30402:{}:listing-{line_suffix}", - hex_64('b') + FIXTURE_BOB_PUBLIC_KEY_HEX )) .unwrap(), listing_event_id: event_id('c'), diff --git a/crates/trade/tests/operational_listing_conformance.rs b/crates/trade/tests/operational_listing_conformance.rs @@ -157,7 +157,7 @@ fn address_valid(vector: &Vector) { let actual = json!({ "address": parsed.address.as_str(), "kind": parsed.kind, - "seller_pubkey": parsed.seller_pubkey.as_str(), + "seller_pubkey": parsed.seller_pubkey.to_hex(), "listing_id": parsed.listing_id.as_str(), }); assert_eq!(actual, vector.expected, "{}", vector.id); @@ -190,6 +190,7 @@ fn address_error_value(error: &RadrootsIdParseError) -> Value { "actual": actual, }), RadrootsIdParseError::InvalidCharacter => json!({ "kind": "invalid_character" }), + RadrootsIdParseError::InvalidPublicKey => json!({ "kind": "invalid_public_key" }), RadrootsIdParseError::UnexpectedKind { expected, actual } => json!({ "kind": "unexpected_kind", "expected": expected, @@ -276,7 +277,7 @@ fn validation_valid(vector: &Vector, event: &RadrootsSignatureVerifiedEvent) { .unwrap_or_else(|error| panic!("{} failed: {error}", vector.id)); assert_eq!( projection.listing.farm.pubkey, - event.event().author_str(), + event.event().author().to_hex(), "{} decoded farm author drift", vector.id ); diff --git a/crates/transport_nostr/src/publish.rs b/crates/transport_nostr/src/publish.rs @@ -1009,7 +1009,7 @@ fn ensure_raw_event_matches_signed_event( ( "pubkey", event.pubkey.to_hex(), - signed_event.pubkey_str().to_owned(), + signed_event.pubkey().to_hex().to_owned(), ), ( "created_at", diff --git a/tools/xtask/src/contract.rs b/tools/xtask/src/contract.rs @@ -3182,7 +3182,19 @@ struct ConformanceVectorEntry { id: String, kind: String, input: Value, - expected: Value, + expected: Option<Value>, + expected_error_contains: Option<String>, +} + +impl ConformanceVectorEntry { + fn expected_value(&self) -> Result<&Value, String> { + self.expected.as_ref().ok_or_else(|| { + format!( + "conformance vector {} does not define an expected output", + self.id + ) + }) + } } impl ReleaseContractFile { @@ -3726,15 +3738,27 @@ fn validate_conformance_schema(workspace_root: &Path) -> Result<(), String> { "required", &path, )?; - let expected_item_required = BTreeSet::from([ - "expected".to_string(), - "id".to_string(), - "input".to_string(), - "kind".to_string(), - ]); + let expected_item_required = + BTreeSet::from(["id".to_string(), "input".to_string(), "kind".to_string()]); if item_required != expected_item_required { return Err(format!( - "vector item schema in {} must require id, kind, input, and expected", + "vector item schema in {} must require id, kind, and input", + path.display() + )); + } + let expected_one_of = serde_json::json!([ + { + "required": ["expected"], + "not": {"required": ["expected_error_contains"]} + }, + { + "required": ["expected_error_contains"], + "not": {"required": ["expected"]} + } + ]); + if items.get("oneOf") != Some(&expected_one_of) { + return Err(format!( + "vector item schema in {} must require exactly one of expected or expected_error_contains", path.display() )); } @@ -3787,6 +3811,20 @@ fn validate_conformance_schema(workspace_root: &Path) -> Result<(), String> { )); } } + validate_string_schema_property( + item_properties + .get("expected_error_contains") + .ok_or_else(|| { + format!( + "vector item schema in {} missing expected_error_contains property", + path.display() + ) + })?, + "expected_error_contains", + &path, + Some(1), + None, + )?; Ok(()) } @@ -4370,6 +4408,24 @@ fn validate_conformance_vector_file( entry.id )); } + match (&entry.expected, &entry.expected_error_contains) { + (Some(_), None) => {} + (None, Some(fragment)) if !fragment.trim().is_empty() => {} + (None, Some(_)) => { + return Err(format!( + "conformance vector {} entry {} expected_error_contains must not be blank", + path.display(), + entry.id + )); + } + _ => { + return Err(format!( + "conformance vector {} entry {} must define exactly one of expected or expected_error_contains", + path.display(), + entry.id + )); + } + } } Ok(vector) } @@ -4566,7 +4622,7 @@ fn validate_knowledge_manifest_vector_semantics( ("schema_version", schema_version), ("registry_version", registry_version), ] { - let actual = case.expected.get(field).and_then(Value::as_u64); + let actual = case.expected_value()?.get(field).and_then(Value::as_u64); if actual != Some(expected) { return Err(format!( "knowledge manifest conformance expected {field} drift: expected {expected}, got {}", @@ -6660,8 +6716,9 @@ fn validate_deletion_suppression_vector_shape( entry: &ConformanceVectorEntry, ) -> Result<(), String> { validate_deletion_suppression_forbidden_material(&entry.input, &format!("{}.input", entry.id))?; + let expected_value = entry.expected_value()?; validate_deletion_suppression_forbidden_material( - &entry.expected, + expected_value, &format!("{}.expected", entry.id), )?; @@ -6711,7 +6768,7 @@ fn validate_deletion_suppression_vector_shape( request_ids.insert(event.id); } - let expected = deletion_object(&entry.expected, &format!("{} expected", entry.id))?; + let expected = deletion_object(expected_value, &format!("{} expected", entry.id))?; validate_deletion_object_keys( expected, &format!("{} expected", entry.id), @@ -7004,7 +7061,8 @@ fn validate_deletion_suppression_forbidden_material( fn validate_deletion_vector_shape(entry: &ConformanceVectorEntry) -> Result<(), String> { validate_deletion_forbidden_metadata(&entry.input, &format!("{}.input", entry.id))?; - validate_deletion_forbidden_metadata(&entry.expected, &format!("{}.expected", entry.id))?; + let expected_value = entry.expected_value()?; + validate_deletion_forbidden_metadata(expected_value, &format!("{}.expected", entry.id))?; let input = deletion_object(&entry.input, &format!("{} input", entry.id))?; let is_authored = entry @@ -7104,7 +7162,7 @@ fn validate_deletion_vector_shape(entry: &ConformanceVectorEntry) -> Result<(), } } - let expected = deletion_object(&entry.expected, &format!("{} expected", entry.id))?; + let expected = deletion_object(expected_value, &format!("{} expected", entry.id))?; if !is_valid { validate_deletion_object_keys(expected, &format!("{} expected", entry.id), &["error"])?; if !expected @@ -9669,7 +9727,7 @@ vector = "contracts/conformance/vectors/operational_listing/build_draft.v1.json" "type": "array", "items": { "type": "object", - "required": ["id", "kind", "input", "expected"], + "required": ["id", "kind", "input"], "properties": { "id": { "type": "string", @@ -9680,8 +9738,22 @@ vector = "contracts/conformance/vectors/operational_listing/build_draft.v1.json" "minLength": 1 }, "input": {}, - "expected": {} + "expected": {}, + "expected_error_contains": { + "type": "string", + "minLength": 1 + } }, + "oneOf": [ + { + "required": ["expected"], + "not": {"required": ["expected_error_contains"]} + }, + { + "required": ["expected_error_contains"], + "not": {"required": ["expected"]} + } + ], "additionalProperties": false } } @@ -9855,8 +9927,10 @@ crates = ["radroots_a", "radroots_b", "radroots_c", "radroots_d", "radroots_e"] .find(|entry| entry.id == "knowledge_manifest_fields_valid_001") .expect("knowledge manifest case"); case.expected - .as_object_mut() + .as_mut() .expect("knowledge manifest expected output") + .as_object_mut() + .expect("knowledge manifest expected output object") .insert("registry_version".to_string(), Value::from(1_u64)); let error = validate_knowledge_manifest_vector_semantics(&manifest, &vector) .expect_err("stale expected registry version must fail"); @@ -9994,7 +10068,8 @@ crates = ["radroots_a", "radroots_b", "radroots_c", "radroots_d", "radroots_e"] id: "unclaimed_post_case".to_string(), kind: "social.post.unclaimed.valid".to_string(), input: Value::Object(Default::default()), - expected: Value::Object(Default::default()), + expected: Some(Value::Object(Default::default())), + expected_error_contains: None, }); let error = validate_post_operation_inventory(&manifest, &vector) .expect_err("unclaimed post vector kind must fail"); @@ -10220,7 +10295,8 @@ crates = ["radroots_a", "radroots_b", "radroots_c", "radroots_d", "radroots_e"] id: "unclaimed_comment_case".to_string(), kind: "social.comment.project_verified_event.shadow".to_string(), input: Value::Object(Default::default()), - expected: Value::Object(Default::default()), + expected: Some(Value::Object(Default::default())), + expected_error_contains: None, }); let error = validate_comment_operation_inventory(&manifest, &vector) .expect_err("unclaimed Comment vector kind must fail"); @@ -10241,7 +10317,8 @@ crates = ["radroots_a", "radroots_b", "radroots_c", "radroots_d", "radroots_e"] id: "legacy_comment".to_string(), kind: "social.comment.build_tags".to_string(), input: Value::Object(Default::default()), - expected: Value::Object(Default::default()), + expected: Some(Value::Object(Default::default())), + expected_error_contains: None, }], }; @@ -10339,6 +10416,7 @@ crates = ["radroots_a", "radroots_b", "radroots_c", "radroots_d", "radroots_e"] kind: "social.deletion_request.unclaimed.valid".to_string(), input, expected, + expected_error_contains: None, }); let error = validate_deletion_operation_inventory(&manifest, &request_vector, &suppression_vector) @@ -10403,8 +10481,10 @@ crates = ["radroots_a", "radroots_b", "radroots_c", "radroots_d", "radroots_e"] .find(|entry| entry.id == "nip09_project_signed_event_target_without_k") .expect("signed deletion vector") .expected - .as_object_mut() + .as_mut() .expect("projection expected") + .as_object_mut() + .expect("projection expected object") .insert("AuThOrIzAtIoN".to_string(), Value::Bool(true)); let error = validate_deletion_operation_inventory(&manifest, &request_vector, &suppression_vector) @@ -10488,8 +10568,10 @@ crates = ["radroots_a", "radroots_b", "radroots_c", "radroots_d", "radroots_e"] .find(|entry| entry.id == "nip09_suppress_same_author_event_reference") .expect("event-reference suppression vector") .expected - .as_object_mut() + .as_mut() .expect("suppression expected") + .as_object_mut() + .expect("suppression expected object") .get_mut("event_reference") .expect("event-reference evidence") .as_object_mut() @@ -10513,7 +10595,8 @@ crates = ["radroots_a", "radroots_b", "radroots_c", "radroots_d", "radroots_e"] id: "nip09_alternate".to_string(), kind: "social.deletion_request.build_authored_draft.valid".to_string(), input: Value::Object(Default::default()), - expected: Value::Object(Default::default()), + expected: Some(Value::Object(Default::default())), + expected_error_contains: None, }], }; @@ -10606,7 +10689,8 @@ crates = ["radroots_a", "radroots_b", "radroots_c", "radroots_d", "radroots_e"] id: "food_unclaimed_case".to_string(), kind: "food_availability.unclaimed.valid".to_string(), input: Value::Object(Default::default()), - expected: Value::Object(Default::default()), + expected: Some(Value::Object(Default::default())), + expected_error_contains: None, }); let error = validate_food_availability_operation_inventory(&manifest, &vector) .expect_err("unclaimed FoodAvailability vector kind must fail"); @@ -12951,13 +13035,14 @@ rust_package = "radroots_sdk" let invalid_vector_root = create_synthetic_workspace("operation_contract_invalid_vector"); add_operation_contract_files(&invalid_vector_root); + let invalid_vector_path = invalid_vector_root + .join("contracts") + .join("conformance") + .join("vectors") + .join("profile") + .join("metadata.v1.json"); write_file( - &invalid_vector_root - .join("contracts") - .join("conformance") - .join("vectors") - .join("profile") - .join("metadata.v1.json"), + &invalid_vector_path, r#"{ "suite": "profile", "contract_version": "1.0.0", @@ -12975,7 +13060,48 @@ rust_package = "radroots_sdk" let err = validate_generic_contract_bundle(&bundle).expect_err("invalid vector should fail"); assert!(err.contains("metadata.v1.json")); - assert!(err.contains("parse")); + assert!(err.contains("exactly one of expected or expected_error_contains")); + + write_file( + &invalid_vector_path, + r#"{ + "suite": "profile", + "contract_version": "1.0.0", + "vectors": [ + { + "id": "profile_build_authored_draft_minimal_001", + "kind": "profile.build_authored_draft", + "input": {}, + "expected": {}, + "expected_error_contains": "invalid" + } + ] +} +"#, + ); + let err = validate_generic_contract_bundle(&bundle) + .expect_err("vector with two result authorities should fail"); + assert!(err.contains("exactly one of expected or expected_error_contains")); + + write_file( + &invalid_vector_path, + r#"{ + "suite": "profile", + "contract_version": "1.0.0", + "vectors": [ + { + "id": "profile_build_authored_draft_minimal_001", + "kind": "profile.build_authored_draft", + "input": {}, + "expected_error_contains": " " + } + ] +} +"#, + ); + let err = validate_generic_contract_bundle(&bundle) + .expect_err("blank expected error fragment should fail"); + assert!(err.contains("expected_error_contains must not be blank")); let _ = fs::remove_dir_all(&invalid_vector_root); let root = create_synthetic_workspace("operation_contract_vector_path"); diff --git a/tools/xtask/src/contract/admission_authority.rs b/tools/xtask/src/contract/admission_authority.rs @@ -374,7 +374,7 @@ fn validate_vector( )); } let expected = exact_object( - &vector.expected, + vector.expected_value()?, &["contract_id", "event_id", "variant"], &format!("{}.expected", vector.id), )?; @@ -393,7 +393,7 @@ fn validate_vector( )); } let expected = exact_object( - &vector.expected, + vector.expected_value()?, &["error_code", "error_variant", "event_id"], &format!("{}.expected", vector.id), )?; diff --git a/tools/xtask/src/contract/food_availability_projection.rs b/tools/xtask/src/contract/food_availability_projection.rs @@ -104,7 +104,7 @@ const IMMUTABLE_PREDECESSOR_ARTIFACTS: [ImmutableArtifactSpec; 9] = [ ImmutableArtifactSpec { relative: MANIFEST_RELATIVE, byte_length: 17_455, - sha256: "33b93a3c87ce428e8aa6f5e92643c77203d9aa006c53ce96f3562fe6d68ffd23", + sha256: "02dfe1b450fbdac16e718888215b4dd5c85d8975440fa21e8f439fb24c2b2990", }, ImmutableArtifactSpec { relative: MANIFEST_SCHEMA_RELATIVE, @@ -114,12 +114,12 @@ const IMMUTABLE_PREDECESSOR_ARTIFACTS: [ImmutableArtifactSpec; 9] = [ ImmutableArtifactSpec { relative: MANIFEST_SHA256_RELATIVE, byte_length: 65, - sha256: "4ac4c79a946ccb1a11726cbafc18e2e016f08f3f6797964400dea3494c66dbc5", + sha256: "85446b0c05bed6f2187f85c505db95078f7457ad17fe62fd596611064a275a0e", }, ImmutableArtifactSpec { relative: GENERATED_DESCRIPTOR_RELATIVE, byte_length: 21_437, - sha256: "90908da53ab9572f45f5916ccc2652736b7ea26ba6dd202a4f69af1e651b564b", + sha256: "69730956d3f9f7d3b06b3fe4bd49c818e6dd549dc1bdda73fd126e39e8031f44", }, ImmutableArtifactSpec { relative: RESULT_VECTOR_CANONICAL_RELATIVE, @@ -133,8 +133,8 @@ const IMMUTABLE_PREDECESSOR_ARTIFACTS: [ImmutableArtifactSpec; 9] = [ }, ImmutableArtifactSpec { relative: RESULT_VECTOR_EXECUTOR_RELATIVE, - byte_length: 34_075, - sha256: "9e8e11abae7bbc7dda30eab6f0a79074ffc3761aa6b955cff58c4c62fa581aa3", + byte_length: 34_078, + sha256: "59e20d81562299cf9dd942dd637b5ca404c7aacc98c7ce3fbf1e14751c1b2d9b", }, ImmutableArtifactSpec { relative: MIGRATION_UP_RELATIVE, @@ -1775,7 +1775,7 @@ fn validate_food_projection_audit_authority(source: &str) -> Result<(), String> validate_projection_source_transition(connection, &projection).await?; validate_fts_row(connection, &projection).await?; actual_coordinates.push(( - projection.pubkey().as_str().to_owned(), + projection.pubkey().to_hex(), projection.identifier().as_str().to_owned(), projection.event_id().as_str().to_owned(), projection.event_seq(), @@ -1869,7 +1869,7 @@ fn validate_food_projection_audit_authority(source: &str) -> Result<(), String> validate_projection_source_transition(connection, &projection).await?; validate_fts_row(connection, &projection).await?; actual_coordinates.push(( - projection.pubkey().as_str().to_owned(), + projection.pubkey().to_hex(), projection.identifier().as_str().to_owned(), projection.event_id().as_str().to_owned(), projection.event_seq(), @@ -1976,7 +1976,7 @@ fn validate_food_projection_audit_authority(source: &str) -> Result<(), String> let authoritative: i64 = sqlx::query_scalar({SOURCE_TRANSITION_QUERY:?},) .bind(projection.source_transition_seq()) .bind(projection.source_generation().as_bytes().as_slice()) - .bind(projection.pubkey().as_str()) + .bind(projection.pubkey().to_hex()) .bind(projection.identifier().as_str()) .bind(projection.event_id().as_str()) .bind(projection.event_seq()) diff --git a/tools/xtask/src/contract/nip09_reconciliation.rs b/tools/xtask/src/contract/nip09_reconciliation.rs @@ -215,11 +215,11 @@ const GOVERNED_DEPENDENCY_TABLE_SHA256: [(&str, &str); 7] = [ ), ( EVENT_CARGO_MANIFEST_RELATIVE, - "6e21eb3a0e276ed96ee42d557794097c87e51c928c5ba78e63986cea4f704105", + "543b11b38bb0e3c6074f478cede97cb48f901b3bea0ffa1cc4b8e4a3777509b3", ), ( EVENT_CODEC_CARGO_MANIFEST_RELATIVE, - "e135922812764cff3d3552bee4f953fa827b9a593d00fda081e93f6dc04c860d", + "9510aa7a69335ef72bdeb76e048b17e8de044bf9d75847f09e01e3f37cca99f1", ), ( BLOSSOM_CARGO_MANIFEST_RELATIVE, @@ -227,7 +227,7 @@ const GOVERNED_DEPENDENCY_TABLE_SHA256: [(&str, &str); 7] = [ ), ( EVENT_STORE_CARGO_MANIFEST_RELATIVE, - "3f34cc54eebaad1ae414905a5376bc3e4eb97369bab62479f365c40c26743531", + "8ecd900f34ea701429e326911dff0ed49364b4b5aee654ee9f68b0c1e1bf7cbf", ), ( TRANSPORT_CARGO_MANIFEST_RELATIVE, @@ -235,7 +235,7 @@ const GOVERNED_DEPENDENCY_TABLE_SHA256: [(&str, &str); 7] = [ ), ( "Cargo.toml#governed-workspace-dependencies", - "2652382f63714f1f9fb6518c051c16b9b0ee775634b2c7b7b066e5e56ed60dd5", + "3c7294555fa6b99fe9cf4d50d3bdfd8c4709abd5a75ce80bdf2cdfb6fdc059ef", ), ]; @@ -301,8 +301,8 @@ const IMMUTABLE_PREDECESSOR_ARTIFACTS: [ImmutableArtifactSpec; 11] = [ }, ImmutableArtifactSpec { relative: RESULT_VECTOR_EXECUTOR_RELATIVE, - byte_length: 18_446, - sha256: "ca2a2bf54062aa6ddf2e553fd624c7217a01ad56309487ce73fa58c47c06c208", + byte_length: 18_451, + sha256: "9e9cc8d2f2382da6c73e78d73d41015559a5a3649b797cce13d7aafa9bbcc8d7", }, ImmutableArtifactSpec { relative: MIGRATION_V1_UP_RELATIVE, @@ -2495,10 +2495,15 @@ pub(super) fn validate_nip09_predecessor_production_sources_under_lock( }) .collect::<Vec<_>>(); if current_impls != expected_impls { - return Err( - "unchanged predecessor impl-resolution authority drifted from the immutable manifest" - .to_owned(), - ); + let expected_set = expected_impls.iter().collect::<BTreeSet<_>>(); + let current_set = current_impls.iter().collect::<BTreeSet<_>>(); + let drifted_paths = expected_set + .symmetric_difference(¤t_set) + .map(|item| item.path.as_str()) + .collect::<BTreeSet<_>>(); + return Err(format!( + "unchanged predecessor impl-resolution authority drifted from the immutable manifest at {drifted_paths:?}" + )); } } @@ -12747,7 +12752,7 @@ fn validate_source_maintenance_runtime_token_authority( workspace_root: &Path, ) -> Result<(), String> { const SOURCE_RUNTIME_AST_SHA256: &str = - "181576a5de365cf664b8a87091c30b0389ce0be90e7d1cc16fd7170342f6c2bc"; + "c52b1acee9261d45590d8b443f10ad4fdd539fa8d6227e4ca8bc09c593c4c2b6"; const FUNCTION_SPECS: [(&str, &str, &str); 4] = [ ( EVENT_STORE_PROTOCOL_RECONCILIATION_SOURCE_RELATIVE, diff --git a/tools/xtask/src/contract/source_maintenance.rs b/tools/xtask/src/contract/source_maintenance.rs @@ -35,7 +35,7 @@ const RETAINED_SOURCE_GENERATION_LIMIT: u32 = 8; const RAW_EVENT_REJECTION_SCAN_BOUND: u64 = RAW_EVENT_COUNT_LIMIT + 1; const RAW_TAG_REJECTION_SCAN_BOUND: u64 = RAW_TAG_COUNT_LIMIT + 1; const RETAINED_GENERATION_REJECTION_SCAN_BOUND: u32 = RETAINED_SOURCE_GENERATION_LIMIT + 1; -const SCHEMA_SHA256: &str = "d526d96ea02be12b4b0aed99e97cfdde17c4474ace67111506a7b900ee78b186"; +const SCHEMA_SHA256: &str = "074f85b663444ac150239ecd8441ea4a96ad83a798a55e22d2e5e2f7ee943a8c"; const HASH_ALGORITHM: &str = "sha256_bytes_v1"; const WRITE_COMMAND: &str = "cargo xtask contract source-maintenance-manifest --write"; @@ -44,7 +44,7 @@ const PREDECESSOR_MANIFEST_RELATIVE: &str = "crates/event_store/contracts/food_availability_projection_v1.manifest.json"; const PREDECESSOR_MANIFEST_BYTE_LENGTH: usize = 17_455; const PREDECESSOR_MANIFEST_SHA256: &str = - "33b93a3c87ce428e8aa6f5e92643c77203d9aa006c53ce96f3562fe6d68ffd23"; + "02dfe1b450fbdac16e718888215b4dd5c85d8975440fa21e8f439fb24c2b2990"; const NIP09_HOOK_ID: &str = "nip09_reconciliation_v1"; const NIP09_MANIFEST_SHA256: &str = "74af832420ffbaa9805e89df3c0b34f126a443e1598f757e3372f407f9003b77"; @@ -275,6 +275,170 @@ const SOURCE_SPECS: &[SourceSpec] = &[ path: "crates/core/src/unit.rs", }, SourceSpec { + role: "blossom_hash_authority", + path: "crates/blossom/src/hash.rs", + }, + SourceSpec { + role: "blossom_url_authority", + path: "crates/blossom/src/url.rs", + }, + SourceSpec { + role: "event_contract_facade", + path: "crates/event/src/contract.rs", + }, + SourceSpec { + role: "event_contract_registry_v7_authority", + path: "crates/event/src/contract/registry_v7.rs", + }, + SourceSpec { + role: "event_envelope_authority", + path: "crates/event/src/envelope.rs", + }, + SourceSpec { + role: "event_head_facade", + path: "crates/event/src/event_head.rs", + }, + SourceSpec { + role: "event_head_v1_authority", + path: "crates/event/src/event_head/v1.rs", + }, + SourceSpec { + role: "event_ids_authority", + path: "crates/event/src/ids.rs", + }, + SourceSpec { + role: "event_trade_authority", + path: "crates/event/src/trade.rs", + }, + SourceSpec { + role: "event_kinds_authority", + path: "crates/event/src/kinds.rs", + }, + SourceSpec { + role: "event_tags_authority", + path: "crates/event/src/tags.rs", + }, + SourceSpec { + role: "event_draft_authority", + path: "crates/event/src/draft.rs", + }, + SourceSpec { + role: "event_calendar_authority", + path: "crates/event/src/calendar.rs", + }, + SourceSpec { + role: "event_classified_listing_authority", + path: "crates/event/src/classified_listing.rs", + }, + SourceSpec { + role: "event_profile_authority", + path: "crates/event/src/profile.rs", + }, + SourceSpec { + role: "event_post_authority", + path: "crates/event/src/post.rs", + }, + SourceSpec { + role: "event_comment_authority", + path: "crates/event/src/comment.rs", + }, + SourceSpec { + role: "event_food_availability_authority", + path: "crates/event/src/food_availability.rs", + }, + SourceSpec { + role: "event_deletion_authority", + path: "crates/event/src/deletion.rs", + }, + SourceSpec { + role: "event_relay_hint_authority", + path: "crates/event/src/relay_hint.rs", + }, + SourceSpec { + role: "event_media_authority", + path: "crates/event/src/media.rs", + }, + SourceSpec { + role: "event_social_authority", + path: "crates/event/src/social.rs", + }, + SourceSpec { + role: "event_wire_facade", + path: "crates/event/src/wire.rs", + }, + SourceSpec { + role: "event_wire_v1_authority", + path: "crates/event/src/wire/v1.rs", + }, + SourceSpec { + role: "event_codec_verification_facade", + path: "crates/event_codec/src/verification.rs", + }, + SourceSpec { + role: "event_codec_verification_v1_authority", + path: "crates/event_codec/src/verification/v1.rs", + }, + SourceSpec { + role: "event_codec_registry_v7_admission_authority", + path: "crates/event_codec/src/admission/registry_v7.rs", + }, + SourceSpec { + role: "event_codec_profile_inbound_facade", + path: "crates/event_codec/src/profile/inbound.rs", + }, + SourceSpec { + role: "event_codec_profile_registry_v7_authority", + path: "crates/event_codec/src/profile/inbound/registry_v7.rs", + }, + SourceSpec { + role: "event_codec_post_inbound_facade", + path: "crates/event_codec/src/post/inbound.rs", + }, + SourceSpec { + role: "event_codec_post_registry_v7_authority", + path: "crates/event_codec/src/post/inbound/registry_v7.rs", + }, + SourceSpec { + role: "event_codec_reply_inbound_facade", + path: "crates/event_codec/src/reply/inbound.rs", + }, + SourceSpec { + role: "event_codec_reply_registry_v7_authority", + path: "crates/event_codec/src/reply/inbound/registry_v7.rs", + }, + SourceSpec { + role: "event_codec_comment_inbound_facade", + path: "crates/event_codec/src/comment/inbound.rs", + }, + SourceSpec { + role: "event_codec_comment_registry_v7_authority", + path: "crates/event_codec/src/comment/inbound/registry_v7.rs", + }, + SourceSpec { + role: "event_codec_deletion_facade", + path: "crates/event_codec/src/deletion/mod.rs", + }, + SourceSpec { + role: "event_codec_deletion_reconciliation_v1_authority", + path: "crates/event_codec/src/deletion/reconciliation_v1.rs", + }, + SourceSpec { + role: "event_codec_food_inbound_facade", + path: "crates/event_codec/src/food_availability/inbound.rs", + }, + SourceSpec { + role: "event_codec_food_registry_v7_authority", + path: "crates/event_codec/src/food_availability/inbound/registry_v7.rs", + }, + SourceSpec { + role: "event_codec_job_traits_authority", + path: "crates/event_codec/src/job/traits.rs", + }, + SourceSpec { + role: "event_store_dependency_authority", + path: "crates/event_store/Cargo.toml", + }, + SourceSpec { role: "event_store_error_and_limits", path: "crates/event_store/src/error.rs", }, @@ -295,6 +459,22 @@ const SOURCE_SPECS: &[SourceSpec] = &[ path: "crates/event_store/src/model.rs", }, SourceSpec { + role: "event_store_reconciliation_v1_model", + path: "crates/event_store/src/model/reconciliation_v1.rs", + }, + SourceSpec { + role: "event_store_reconciliation_v1_ingest_model", + path: "crates/event_store/src/model/ingest_reconciliation_v1.rs", + }, + SourceSpec { + role: "addressable_transition_feed_model", + path: "crates/event_store/src/model/addressable_transition_feed_v1.rs", + }, + SourceSpec { + role: "food_projection_model", + path: "crates/event_store/src/model/food_availability_projection_v1.rs", + }, + SourceSpec { role: "source_generation_rebuild_authority", path: "crates/event_store/src/nip09/reconciliation_v1.rs", }, @@ -307,10 +487,30 @@ const SOURCE_SPECS: &[SourceSpec] = &[ path: "crates/event_store/src/store.rs", }, SourceSpec { + role: "addressable_transition_feed_store", + path: "crates/event_store/src/store/addressable_transition_feed_v1.rs", + }, + SourceSpec { + role: "food_projection_store", + path: "crates/event_store/src/store/food_availability_projection_v1.rs", + }, + SourceSpec { + role: "predecessor_post_core_v1_extension", + path: "crates/event_store/src/store/post_core_extensions_v1.rs", + }, + SourceSpec { + role: "predecessor_post_core_v1_storage", + path: "crates/event_store/src/store/post_core_storage_v1.rs", + }, + SourceSpec { role: "raw_ingest_capacity_authority", path: "crates/event_store/src/store/protocol_reconciliation_v1.rs", }, SourceSpec { + role: "predecessor_protocol_storage", + path: "crates/event_store/src/store/protocol_storage_v1.rs", + }, + SourceSpec { role: "source_maintenance_runtime", path: "crates/event_store/src/source_maintenance_v1.rs", }, @@ -347,6 +547,8 @@ pub(super) fn source_contract_fixture_source_paths() -> Vec<&'static str> { const PREDECESSOR_SUPERSEDED_SOURCE_PATHS: &[&str] = &[ "Cargo.toml", + "crates/blossom/src/hash.rs", + "crates/blossom/src/url.rs", "crates/core/src/currency.rs", "crates/core/src/decimal.rs", "crates/core/src/money.rs", @@ -354,15 +556,63 @@ const PREDECESSOR_SUPERSEDED_SOURCE_PATHS: &[&str] = &[ "crates/core/src/quantity.rs", "crates/core/src/quantity_price.rs", "crates/core/src/unit.rs", + "crates/event/src/calendar.rs", + "crates/event/src/classified_listing.rs", + "crates/event/src/comment.rs", + "crates/event/src/contract.rs", + "crates/event/src/contract/registry_v7.rs", + "crates/event/src/deletion.rs", + "crates/event/src/draft.rs", + "crates/event/src/envelope.rs", + "crates/event/src/event_head.rs", + "crates/event/src/event_head/v1.rs", + "crates/event/src/food_availability.rs", + "crates/event/src/ids.rs", + "crates/event/src/kinds.rs", + "crates/event/src/media.rs", + "crates/event/src/post.rs", + "crates/event/src/profile.rs", + "crates/event/src/relay_hint.rs", + "crates/event/src/social.rs", + "crates/event/src/tags.rs", + "crates/event/src/trade.rs", + "crates/event/src/wire.rs", + "crates/event/src/wire/v1.rs", + "crates/event_codec/src/admission/registry_v7.rs", + "crates/event_codec/src/comment/inbound.rs", + "crates/event_codec/src/comment/inbound/registry_v7.rs", + "crates/event_codec/src/deletion/mod.rs", + "crates/event_codec/src/deletion/reconciliation_v1.rs", + "crates/event_codec/src/food_availability/inbound.rs", + "crates/event_codec/src/food_availability/inbound/registry_v7.rs", + "crates/event_codec/src/job/traits.rs", + "crates/event_codec/src/post/inbound.rs", + "crates/event_codec/src/post/inbound/registry_v7.rs", + "crates/event_codec/src/profile/inbound.rs", + "crates/event_codec/src/profile/inbound/registry_v7.rs", + "crates/event_codec/src/reply/inbound.rs", + "crates/event_codec/src/reply/inbound/registry_v7.rs", + "crates/event_codec/src/verification.rs", + "crates/event_codec/src/verification/v1.rs", + "crates/event_store/Cargo.toml", "crates/event_store/src/error.rs", "crates/event_store/src/generated.rs", "crates/event_store/src/lib.rs", "crates/event_store/src/migrations.rs", "crates/event_store/src/model.rs", + "crates/event_store/src/model/addressable_transition_feed_v1.rs", + "crates/event_store/src/model/food_availability_projection_v1.rs", + "crates/event_store/src/model/ingest_reconciliation_v1.rs", + "crates/event_store/src/model/reconciliation_v1.rs", "crates/event_store/src/nip09/reconciliation_v1.rs", "crates/event_store/src/schema.rs", "crates/event_store/src/store.rs", + "crates/event_store/src/store/addressable_transition_feed_v1.rs", + "crates/event_store/src/store/food_availability_projection_v1.rs", + "crates/event_store/src/store/post_core_extensions_v1.rs", + "crates/event_store/src/store/post_core_storage_v1.rs", "crates/event_store/src/store/protocol_reconciliation_v1.rs", + "crates/event_store/src/store/protocol_storage_v1.rs", ]; #[cfg(test)] @@ -974,7 +1224,7 @@ fn validate_catalog(catalog: &CatalogDescriptor) -> Result<(), String> { fn validate_migration_identity(up: &FileDescriptor, down: &FileDescriptor) -> Result<(), String> { const UP_BYTE_LENGTH: u64 = 19_841; - const UP_SHA256: &str = "425dc799f392b87f265a6fb81f89c4a1c7a5db8391ab0380970708cb9c66704d"; + const UP_SHA256: &str = "ab2724188f8d08c897eebea2533a635e7c74282a25e84e4c0c37e78b08837a43"; const DOWN_BYTE_LENGTH: u64 = 5_172; const DOWN_SHA256: &str = "fe44fd53c51545c08ea479b385e6781079dab70fc63da2a3c205d727a00ce860"; if up.path != MIGRATION_UP_RELATIVE @@ -1734,7 +1984,7 @@ fn validate_sql_capacity_authority(workspace_root: &Path) -> Result<(), String> "retained_generation_count >= retained_generation_limit", "CREATE TRIGGER radroots_event_store_source_generation_capacity_advance", "CREATE TRIGGER radroots_event_store_source_capacity_marker_close_guard", - "33b93a3c87ce428e8aa6f5e92643c77203d9aa006c53ce96f3562fe6d68ffd23", + "02dfe1b450fbdac16e718888215b4dd5c85d8975440fa21e8f439fb24c2b2990", "8B63C5DDC48A2CC7DB69295238B96D5F814DBA50427C80B4D0079F061E6D3DE0", "capacity.retained_generation_count = (\n SELECT COUNT(*)\n FROM (\n SELECT 1\n FROM radroots_event_store_source_generation\n LIMIT 9\n )\n )", "generation.generation_ordinal = capacity.retained_generation_count", @@ -3196,9 +3446,9 @@ struct DelegatedAuthoritySpec { } const EXECUTABLE_AUTHORITY_AST_SHA256: &str = - "19c405fc91468997aa53f08ebbaed82c526bf4810b2175ad9034d95dc95b8597"; + "88a60544e38b546dbb2c555b0347308eac0c4a3eb66f403ba44d45fb4a5818e6"; const BOUND_AUTHORITY_SOURCE_AST_SHA256: &str = - "ba44c729ebba14e658ec7b48f7ba395fd4e8fb3d597d306df5cfa7010a4f9bac"; + "af59af8101b14f5eacf88b851e0298e3b4b3c97951f6cd4b5a73a5c2a39e6a3e"; #[derive(Clone, Debug, Serialize)] struct ExecutableAuthorityIdentity {