mirror of
https://github.com/Routstr/routstr-core.git
synced 2026-08-09 02:54:37 +00:00
Support RIP-02 alongside NIP-91 for provider discovery protocol
Co-authored-by: db2002dominic <db2002dominic@gmail.com>
This commit is contained in:
co-authored by
db2002dominic
parent
6b1f432c58
commit
2a934dbda4
@@ -33,7 +33,7 @@ sequenceDiagram
|
||||
- **API Key Management** – Hashed keys stored in SQLite with balance tracking and optional expiry/refund address
|
||||
- **Model-Based Pricing** – Convert USD prices in `models.json` to sats using live BTC/USD rates
|
||||
- **Admin Dashboard** – Simple HTML interface at `/admin/` to view balances and API keys
|
||||
- **Discovery** – Fetch available providers from Nostr relays using NIP-91 protocol
|
||||
- **Discovery** – Fetch available providers from Nostr relays using both RIP-02 and NIP-91 protocols
|
||||
- **NIP-91 Auto-Announcement** – Automatically announce this provider to Nostr relays when NSEC is provided
|
||||
- **Docker Support** – Provided `Dockerfile` and `compose.yml` for running with an optional Tor hidden service
|
||||
|
||||
|
||||
+9
-8
@@ -25,13 +25,13 @@ async def query_nostr_relay_for_providers(
|
||||
) -> list[dict[str, Any]]:
|
||||
"""
|
||||
Query a Nostr relay for provider announcements.
|
||||
Searches for NIP-91 (kind:38421) events.
|
||||
Searches for both RIP-02 and NIP-91 (kind:38421) events.
|
||||
"""
|
||||
events = []
|
||||
|
||||
# Build filter for NIP-91 events
|
||||
filter_obj: dict[str, Any] = {
|
||||
"kinds": [38421], # NIP-91 Provider Announcements
|
||||
"kinds": [38421], # Both RIP-02 and NIP-91 Provider Announcements
|
||||
"limit": limit,
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ async def query_nostr_relay_for_providers(
|
||||
def parse_provider_announcement(event: dict[str, Any]) -> dict[str, Any] | None:
|
||||
"""
|
||||
Parse provider announcement events.
|
||||
Handles NIP-91 (kind:38421) format.
|
||||
Handles both RIP-02 and NIP-91 (kind:38421) formats.
|
||||
Returns structured provider data or None if invalid.
|
||||
"""
|
||||
try:
|
||||
@@ -100,7 +100,7 @@ def parse_provider_announcement(event: dict[str, Any]) -> dict[str, Any] | None:
|
||||
version = None
|
||||
|
||||
# Parse NIP-91 format
|
||||
if kind == 38421: # NIP-91 format
|
||||
if kind == 38421: # RIP-02/NIP-91 format
|
||||
for tag in tags:
|
||||
if len(tag) >= 2:
|
||||
if tag[0] == "d":
|
||||
@@ -133,7 +133,7 @@ def parse_provider_announcement(event: dict[str, Any]) -> dict[str, Any] | None:
|
||||
|
||||
# Validate NIP-91 required fields
|
||||
if not endpoint_url or not d_tag:
|
||||
print(f"Invalid NIP-91 announcement - missing required fields: {event['id']}")
|
||||
print(f"Invalid RIP-02/NIP-91 announcement - missing required fields: {event['id']}")
|
||||
return None
|
||||
else:
|
||||
print(f"Unknown event kind: {kind}")
|
||||
@@ -222,11 +222,12 @@ async def get_providers(
|
||||
include_json: bool = False, pubkey: str | None = None
|
||||
) -> dict[str, list[dict[str, Any]]]:
|
||||
"""
|
||||
Discover Routstr providers using NIP-91 specification.
|
||||
Discover Routstr providers using both RIP-02 and NIP-91 specifications.
|
||||
Searches for provider announcement events on Nostr relays:
|
||||
- kind:38421 (NIP-91)
|
||||
- kind:38421 (RIP-02/NIP-91)
|
||||
|
||||
References:
|
||||
- RIP-02: https://github.com/Routstr/protocol/blob/main/RIP-02.md
|
||||
- NIP-91: https://github.com/nostr-protocol/nips/pull/1987
|
||||
"""
|
||||
# Default relays for provider discovery
|
||||
@@ -263,7 +264,7 @@ async def get_providers(
|
||||
|
||||
print(f"Found {len(all_events)} total unique provider announcements")
|
||||
|
||||
# Parse provider announcements according to NIP-91
|
||||
# Parse provider announcements according to RIP-02/NIP-91
|
||||
providers = []
|
||||
for event in all_events:
|
||||
parsed_provider = parse_provider_announcement(event)
|
||||
|
||||
@@ -27,7 +27,7 @@ async def test_providers_endpoint_default_response(
|
||||
{
|
||||
"id": "event1",
|
||||
"pubkey": "test_pubkey1",
|
||||
"kind": 38421, # NIP-91 event kind
|
||||
"kind": 38421, # RIP-02/NIP-91 event kind
|
||||
"created_at": 1234567890,
|
||||
"content": '{"name": "Provider 1", "about": "Test provider 1"}',
|
||||
"tags": [
|
||||
@@ -38,7 +38,7 @@ async def test_providers_endpoint_default_response(
|
||||
{
|
||||
"id": "event2",
|
||||
"pubkey": "test_pubkey2",
|
||||
"kind": 38421, # NIP-91 event kind
|
||||
"kind": 38421, # RIP-02/NIP-91 event kind
|
||||
"created_at": 1234567891,
|
||||
"content": '{"name": "Provider 2", "about": "Test provider 2"}',
|
||||
"tags": [
|
||||
@@ -100,7 +100,7 @@ async def test_providers_endpoint_with_include_json(
|
||||
{
|
||||
"id": "event1",
|
||||
"pubkey": "test_pubkey",
|
||||
"kind": 38421, # NIP-91 event kind
|
||||
"kind": 38421, # RIP-02/NIP-91 event kind
|
||||
"created_at": 1234567890,
|
||||
"content": '{"name": "Test Provider", "about": "A test provider"}',
|
||||
"tags": [
|
||||
@@ -165,13 +165,13 @@ async def test_providers_data_structure_validation(
|
||||
) -> None:
|
||||
"""Test provider data structure contains expected fields"""
|
||||
|
||||
# Mock NIP-91 provider announcement event
|
||||
# Mock RIP-02/NIP-91 provider announcement event
|
||||
mock_events: list[dict[str, Any]] = [
|
||||
{
|
||||
"id": "event1",
|
||||
"pubkey": "test_pubkey",
|
||||
"created_at": 1234567890,
|
||||
"kind": 38421, # NIP-91 event kind
|
||||
"kind": 38421, # RIP-02/NIP-91 event kind
|
||||
"content": '{"name": "Comprehensive Provider", "about": "A comprehensive AI provider"}',
|
||||
"tags": [
|
||||
["d", "provider-123"],
|
||||
@@ -212,7 +212,7 @@ async def test_providers_data_structure_validation(
|
||||
assert "health" in provider_data
|
||||
|
||||
provider_info = provider_data["provider"]
|
||||
# Expected fields from NIP-91 parser
|
||||
# Expected fields from RIP-02/NIP-91 parser
|
||||
expected_fields = ["id", "name", "endpoint_url", "supported_models"]
|
||||
for field in expected_fields:
|
||||
assert field in provider_info
|
||||
@@ -261,7 +261,7 @@ async def test_providers_endpoint_offline_providers(
|
||||
{
|
||||
"id": "event1",
|
||||
"pubkey": "healthy_provider_pubkey",
|
||||
"kind": 38421, # NIP-91 event kind
|
||||
"kind": 38421, # RIP-02/NIP-91 event kind
|
||||
"created_at": 1234567890,
|
||||
"content": '{"name": "Healthy Provider", "about": "Healthy provider announcement"}',
|
||||
"tags": [
|
||||
@@ -272,7 +272,7 @@ async def test_providers_endpoint_offline_providers(
|
||||
{
|
||||
"id": "event2",
|
||||
"pubkey": "offline_provider_pubkey",
|
||||
"kind": 38421, # NIP-91 event kind
|
||||
"kind": 38421, # RIP-02/NIP-91 event kind
|
||||
"created_at": 1234567891,
|
||||
"content": '{"name": "Offline Provider", "about": "Offline provider announcement"}',
|
||||
"tags": [
|
||||
@@ -334,7 +334,7 @@ async def test_providers_endpoint_duplicate_urls(
|
||||
{
|
||||
"id": "event1",
|
||||
"pubkey": "provider_pubkey",
|
||||
"kind": 38421, # NIP-91 event kind
|
||||
"kind": 38421, # RIP-02/NIP-91 event kind
|
||||
"created_at": 1234567890,
|
||||
"content": '{"name": "Provider", "about": "Provider announcement"}',
|
||||
"tags": [
|
||||
@@ -345,7 +345,7 @@ async def test_providers_endpoint_duplicate_urls(
|
||||
{
|
||||
"id": "event2",
|
||||
"pubkey": "other_provider_pubkey",
|
||||
"kind": 38421, # NIP-91 event kind
|
||||
"kind": 38421, # RIP-02/NIP-91 event kind
|
||||
"created_at": 1234567892,
|
||||
"content": '{"name": "Other Provider", "about": "Different provider announcement"}',
|
||||
"tags": [
|
||||
|
||||
Reference in New Issue
Block a user