105 lines
No EOL
3.4 KiB
Python
105 lines
No EOL
3.4 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Manual Nostr profile metadata publisher
|
|
Usage: python test_nostr_connection.py <private_key_hex> <profile_name> <relay_url>
|
|
"""
|
|
import sys
|
|
import json
|
|
import time
|
|
import hashlib
|
|
import secp256k1
|
|
from websocket import create_connection
|
|
|
|
def sign_event(event, public_key_hex, private_key):
|
|
"""Sign a Nostr event"""
|
|
# Create the signature data
|
|
signature_data = json.dumps([
|
|
0,
|
|
public_key_hex,
|
|
event["created_at"],
|
|
event["kind"],
|
|
event["tags"],
|
|
event["content"]
|
|
], separators=(',', ':'), ensure_ascii=False)
|
|
|
|
# Calculate event ID
|
|
event_id = hashlib.sha256(signature_data.encode()).hexdigest()
|
|
event["id"] = event_id
|
|
event["pubkey"] = public_key_hex
|
|
|
|
# Sign the event
|
|
signature = private_key.schnorr_sign(bytes.fromhex(event_id), None, raw=True).hex()
|
|
event["sig"] = signature
|
|
|
|
return event
|
|
|
|
def publish_profile_metadata(private_key_hex, profile_name, relay_url):
|
|
"""Publish a Nostr kind 0 metadata event"""
|
|
try:
|
|
# Convert hex private key to secp256k1 PrivateKey and get public key
|
|
private_key = secp256k1.PrivateKey(bytes.fromhex(private_key_hex))
|
|
public_key_hex = private_key.pubkey.serialize()[1:].hex() # Remove the 0x02 prefix
|
|
|
|
print(f"Private key: {private_key_hex}")
|
|
print(f"Public key: {public_key_hex}")
|
|
print(f"Profile name: {profile_name}")
|
|
print(f"Relay URL: {relay_url}")
|
|
print()
|
|
|
|
# Create Nostr kind 0 metadata event
|
|
metadata = {
|
|
"name": profile_name,
|
|
"display_name": profile_name,
|
|
"about": f"Manual profile update for {profile_name}"
|
|
}
|
|
|
|
event = {
|
|
"kind": 0,
|
|
"created_at": int(time.time()),
|
|
"tags": [],
|
|
"content": json.dumps(metadata, separators=(',', ':'))
|
|
}
|
|
|
|
# Sign the event
|
|
signed_event = sign_event(event, public_key_hex, private_key)
|
|
|
|
print(f"Signed event: {json.dumps(signed_event, indent=2)}")
|
|
print()
|
|
|
|
# Connect to relay and publish
|
|
print(f"Connecting to relay: {relay_url}")
|
|
ws = create_connection(relay_url, timeout=15)
|
|
print("✅ Connected successfully!")
|
|
|
|
# Send the event
|
|
event_message = f'["EVENT",{json.dumps(signed_event)}]'
|
|
print(f"Sending EVENT: {event_message}")
|
|
ws.send(event_message)
|
|
|
|
# Wait for response
|
|
try:
|
|
response = ws.recv()
|
|
print(f"✅ Relay response: {response}")
|
|
except Exception as e:
|
|
print(f"⚠️ No immediate response: {e}")
|
|
|
|
# Close connection
|
|
ws.close()
|
|
print("✅ Connection closed successfully")
|
|
print(f"Profile metadata for '{profile_name}' published successfully!")
|
|
|
|
except Exception as e:
|
|
print(f"❌ Failed to publish profile: {e}")
|
|
raise
|
|
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) != 4:
|
|
print("Usage: python test_nostr_connection.py <private_key_hex> <profile_name> <relay_url>")
|
|
print("Example: python test_nostr_connection.py abc123... 'My Name' wss://relay.example.com")
|
|
sys.exit(1)
|
|
|
|
private_key_hex = sys.argv[1]
|
|
profile_name = sys.argv[2]
|
|
relay_url = sys.argv[3]
|
|
|
|
publish_profile_metadata(private_key_hex, profile_name, relay_url) |