Skip to main content

Nostr profile management for OpenClaw AI agents — publish, read, and update kind 0 metadata

Project description

nostr-profile

Give your AI agent a face.

A keypair is proof of identity — but it's just numbers. A profile puts a name, a picture, and a description to that code. It makes it easier for people and other entities to relate to your agent and stay connected in the public social space.

And while someone could try to create a fake account using your agent's name, the npub is cryptographic proof of identity that can't be faked. It's the best way for anyone to be sure they're connecting to the real thing.

Everything in a Nostr profile is public — just like any social platform. The name, bio, and images are visible to anyone on the Nostr network and the public internet.

How It Fits Together

nostr-profile is part of the NSE sovereign identity ecosystem:

  • NostrKey gives the agent its keypair — the cryptographic root
  • nostr-profile uses that keypair to publish and manage the agent's public identity
  • sense-memory uses it for encrypted persistence
  • NostrCalendar uses it for scheduling
  • NostrSocial uses it for the social graph

The keypair is who you are. The profile is how the world sees you.

Install

pip install nostr-profile

Quick Start

import asyncio
from nostrkey import Identity
from nostr_profile import Profile, publish_profile, get_profile

async def main():
    # Load identity from encrypted file (passphrase from env var)
    import os
    identity = Identity.load("my-identity.nostrkey", passphrase=os.environ["NOSTRKEY_PASSPHRASE"])
    relay = "wss://relay.damus.io"

    # Publish your profile
    profile = Profile(
        name="Johnny5",
        about="An OpenClaw AI companion by Humanjava",
        picture="https://example.com/johnny5-avatar.png",
        nip05="johnny5@example.com",
    )
    event_id = await publish_profile(identity, profile, relay)
    print(f"Profile published: {event_id}")
    print(f"View online: https://njump.me/{identity.npub}")

    # Read anyone's profile
    their_profile = await get_profile(identity.public_key_hex, relay)
    if their_profile:
        print(f"{their_profile.name}: {their_profile.about}")

asyncio.run(main())

API

Function Returns Description
publish_profile(identity, profile, relay_url) str Publish a complete profile. Returns event ID.
update_profile(identity, relay_url, **fields) str Update specific fields without clobbering the rest.
get_profile(pubkey_hex, relay_url) Profile | None Read anyone's profile from a relay.

Profile Fields

Field Type Required Description
name str Yes Display name (max 100 chars)
about str No Bio/description (max 2000 chars)
picture str No Avatar URL (HTTPS)
banner str No Banner image URL (HTTPS)
nip05 str No NIP-05 verification (user@domain.tld)
lud16 str No Lightning address (user@domain.tld)
website str No Website URL (HTTPS)

Update Without Clobbering

from nostr_profile import update_profile

# Only changes the about field — everything else stays the same
await update_profile(identity, relay, about="Updated bio for Q2")

Profile Diff

old_profile = await get_profile(pubkey, relay)
new_profile = Profile(name="Johnny5", about="New bio")
changes = old_profile.diff(new_profile)
# {"about": ("Old bio", "New bio")}

NIPs Used

NIP Purpose
NIP-01 Kind 0 metadata (replaceable)
NIP-05 DNS-based verification identifier

OpenClaw Deployment

Quick Start (ClawHub)

clawhub install nostr-profile

Manual Setup

The support_skills/ folder contains ready-to-deploy workspace files. See support_skills/README.md for the full walkthrough.

Short version:

  1. Add nostr-profile to your Dockerfile:
    RUN pip3 install --no-cache-dir --break-system-packages nostr-profile==0.1.7
    
  2. Set NOSTRKEY_PASSPHRASE in your .env file so the agent can sign autonomously
  3. Copy support_skills/setup-profile.py and support_skills/show-profile.py into your OC workspace
  4. Paste the snippet from support_skills/TOOLS-snippet.md into your agent's TOOLS.md

After Setup

Once your agent's profile is published, here are useful things to ask it:

What to ask What it does
"What is your Nostr profile?" Shows name, bio, avatar from local cache
"Update your bio to ..." Publishes updated profile to relay
"Look up npub1..." Fetches someone else's profile from a relay

The agent will also offer to show you the profile online via:

  • njump.mehttps://njump.me/[npub]
  • npub.biohttps://npub.bio/[npub]

What's Next

Now that your agent has a profile, it exists on the Nostr network — an open social protocol with no gatekeepers, no corporate algorithms, no account bans.

Your agent (or you, on its behalf) can use any Nostr-enabled app to:

  • Post content and engage publicly — just like X/Twitter, but on the open internet
  • Have public conversations with humans and other agents
  • Update the profile — change the name, bio, avatar, or banner anytime
  • Build a following — anyone can follow the npub from any Nostr client

Some popular Nostr apps:

App Platform Link
Primal Web, iOS, Android primal.net
Damus iOS damus.io
Amethyst Android github.com/vitorpamplona/amethyst
Coracle Web coracle.social
Snort Web snort.social

No sign-up required — just import the npub or nsec into any of these apps and your agent's profile is already there.

FAQ

Why does the setup script hang?

The script needs to connect to a Nostr relay via WebSocket. If the relay is unreachable (e.g., behind a VPN that blocks certain hosts), the script will hang.

Fix: Try a different relay. wss://relay.damus.io is widely reachable. Pass it as the 4th argument to setup-profile.py.

Why doesn't the agent ask for a passphrase?

The passphrase is read from the NOSTRKEY_PASSPHRASE environment variable, set in your .env or docker-compose.yml. The agent can sign events autonomously without asking the operator each time.

Fix: If the env var isn't set, the script will error. Add NOSTRKEY_PASSPHRASE=yourpassphrase to your .env file and restart the container.

Can I see my agent's profile online?

Yes. After publishing, visit:

  • https://njump.me/[your-agent-npub]
  • https://npub.bio/[your-agent-npub]

These are public Nostr profile viewers — anyone can see the profile.

Why can't I upload an image for my profile picture?

The Nostr protocol does not support uploading images. Profile pictures and banners are URLs to images already hosted on the internet — your website, an image host, social media, etc. If you don't have a hosted image, the setup script can generate a unique DiceBear avatar automatically using "auto".

How do I update my agent's name or bio?

Use update-profile.py from support_skills/:

python3 update-profile.py --name "New Name"
python3 update-profile.py --about "New bio" --picture "https://example.com/photo.jpg"

Only the fields you pass will change. Everything else stays the same.

Links

License

MIT — Humanjava Enterprises Inc.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nostr_profile-0.1.7.tar.gz (22.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nostr_profile-0.1.7-py3-none-any.whl (10.2 kB view details)

Uploaded Python 3

File details

Details for the file nostr_profile-0.1.7.tar.gz.

File metadata

  • Download URL: nostr_profile-0.1.7.tar.gz
  • Upload date:
  • Size: 22.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for nostr_profile-0.1.7.tar.gz
Algorithm Hash digest
SHA256 1103c85c146cb3c0e574b411605445c7c1ae700fc92554a597e6ff4e2427a681
MD5 9b125d3450157c37361e48b744a3199d
BLAKE2b-256 ca1e5f668fc9ebd6377825a7ae8fad24ece6400a7aaff8e852e6c8b9e41e7e39

See more details on using hashes here.

File details

Details for the file nostr_profile-0.1.7-py3-none-any.whl.

File metadata

  • Download URL: nostr_profile-0.1.7-py3-none-any.whl
  • Upload date:
  • Size: 10.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for nostr_profile-0.1.7-py3-none-any.whl
Algorithm Hash digest
SHA256 e7763c73f4eaa37c693ed4603b48ccd8d26129e104169f9dba04cf458ffbf623
MD5 2437328d79e8067b2f61e52ba5c3b624
BLAKE2b-256 1b9324faa942210cc2ece5b945f603f50815c14b62655ec28c0185e3a03d707b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page