draft optional
Authors: Astroport.ONE Contributors
Status: Draft for Community Review
Version: 2.0
Repository: github.com/papiche/NIP-101
NIP-101 defines a comprehensive protocol for decentralized identity management, geographic coordination, and verifiable credentials on Nostr. It extends the Nostr protocol with four integrated systems:
- Hierarchical GeoKeys - Nostr keypairs derived from geographic coordinates
- Decentralized Identity (DID) - W3C-compliant identities stored as Nostr events (kind 30800)
- Oracle System - Multi-signature permit management using Web of Trust (kinds 30500-30503)
- ORE System - Environmental obligations attached to geographic cells (kinds 30312-30313)
This NIP enables geographically localized communication, self-sovereign identity, peer-validated credentials, and ecological commitment tracking on a fully decentralized network.
┌─────────────────────────────────────────────────────────────────┐ │ UPlanet Event Kinds Map │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ CORE NOSTR NIP-101 EXTENSIONS │ │ ───────── ────────────────── │ │ 0 Profile 30800 DID Document │ │ 1 Text Note 30500 Permit Definition │ │ 3 Contacts 30501 Permit Request │ │ 5 Deletion 30502 Permit Attestation │ │ 6 Repost 30503 Permit Credential (VC) │ │ 7 Reaction │ │ │ │ MEDIA (NIP-71) ORE SYSTEM (NIP-53 Extension) │ │ ────────────── ───────────────────────────── │ │ 21 Video Normal 30312 ORE Meeting Space │ │ 22 Video Short 30313 ORE Verification │ │ 1063 File Metadata │ │ │ │ SOCIAL BADGES (NIP-58) │ │ ────── ─────────────── │ │ 42 Channel Message (UMAP) 30009 Badge Definition │ │ 22242 Auth (Twin-Key) 8 Badge Award │ │ 30008 Profile Badges │ │ │ │ CONTENT INVENTORY (New) │ │ ─────── ─────────────── │ │ 30023 Long-form Article 30312 + inventory_type tag │ │ 30024 Draft + inventory_name tag │ │ + contract tag │ │ │ └─────────────────────────────────────────────────────────────────┘
Current Nostr implementations lack:
- Geographic context for location-based communication
- Standardized identity documents for self-sovereign identity
- Verifiable credentials for competence and authority
- Environmental accountability mechanisms
NIP-101 provides a unified protocol that:
- ✅ Creates localized Nostr feeds (UMAP, SECTOR, REGION)
- ✅ Implements W3C-compliant DIDs on Nostr (no centralized registries)
- ✅ Enables peer-validated licensing (driver's license, professional certifications)
- ✅ Tracks environmental commitments with economic incentives
- ✅ Supports constellation synchronization across multiple relays
Nostr keypairs are deterministically derived from geographic coordinates and a namespace string.
Seed Format:
"{UPLANETNAME}_{FORMATTED_LATITUDE}" "{UPLANETNAME}_{FORMATTED_LONGITUDE}"
Used as libsodium salt & pepper for deterministic key generation.
| Level | Precision | Area Size | Example Seed |
|---|---|---|---|
| UMAP | 0.01° | ~1.2 km² | "UPlanetV148.85-2.34" |
| SECTOR | 0.1° | ~100 km² | "UPlanetV148.8-2.3" |
| REGION | 1.0° | ~10,000 km² | "UPlanetV148-2" |
Uses the Astroport keygen tool to generate:
- NOSTR keypair (secp256k1)
- IPFS key (ed25519)
- Ğ1 wallet (ed25519)
- Bitcoin address (secp256k1)
All from the same seed, creating a Twin-Key mechanism.
DIDs are stored as Parameterized Replaceable Events (NIP-33).
Note: We use kind 30800 instead of 30311 to avoid conflict with NIP-53 (Live Event), which officially uses kind 30311.
{
"kind": 30800,
"tags": [
["d", "did"],
["t", "uplanet"],
["t", "did-document"]
],
"content": "{JSON_DID_DOCUMENT}"
}{
"@context": [
"https://www.w3.org/ns/did/v1",
"https://w3id.org/security/suites/ed25519-2020/v1"
],
"id": "did:nostr:<hex_pubkey>",
"verificationMethod": [{
"id": "did:nostr:<hex_pubkey>#key-1",
"type": "Ed25519VerificationKey2020",
"controller": "did:nostr:<hex_pubkey>",
"publicKeyMultibase": "z<base58btc_encoded_key>"
}],
"service": [
{
"id": "#ipfs-drive",
"type": "IPFSDrive",
"serviceEndpoint": "ipns://<ipfs_key>/<email>/APP"
},
{
"id": "#g1-wallet",
"type": "Ğ1Wallet",
"serviceEndpoint": "g1:<g1_pubkey>"
}
],
"verifiableCredential": [
{
"@context": "https://www.w3.org/2018/credentials/v1",
"id": "urn:uuid:...",
"type": ["VerifiableCredential", "UPlanetLicense"],
"issuer": "did:nostr:<authority_hex>",
"credentialSubject": {
"id": "did:nostr:<subject_hex>",
"license": "PERMIT_ORE_V1"
}
}
],
"metadata": {
"email": "user@example.com",
"contractStatus": "active",
"created": "2024-01-01T12:00:00Z",
"updated": "2025-10-30T14:30:00Z"
}
}- Format:
did:nostr:<hex_pubkey> - Query: Subscribe to
kind:30800events wherepubkey == <hex_pubkey> - Verification: Use the embedded
verificationMethodto verify signatures
- ✅ No centralized registries (Nostr relays are the source of truth)
- ✅ Self-sovereign (users control their identity via private key)
- ✅ W3C compliant (works with standard DID resolvers)
- ✅ Multi-chain (links NOSTR, IPFS, Ğ1, Bitcoin)
- ✅ Verifiable Credentials (embedded in DID document)
The Oracle System enables peer-validated certification using the Web of Trust model.
| Kind | Name | Description | Signed by | Replaceability |
|---|---|---|---|---|
| 30500 | Permit Definition | License type definition | UPLANETNAME.G1 |
Parameterized Replaceable |
| 30501 | Permit Request | Application from user | Applicant | Parameterized Replaceable |
| 30502 | Permit Attestation | Expert signature | Attester | Parameterized Replaceable |
| 30503 | Permit Credential | Final VC | UPLANETNAME.G1 |
Parameterized Replaceable |
{
"kind": 30500,
"pubkey": "<UPLANETNAME_G1_hex>",
"tags": [
["d", "PERMIT_ORE_V1"],
["t", "uplanet"],
["t", "permit-definition"]
],
"content": "{
\"id\": \"PERMIT_ORE_V1\",
\"name\": \"ORE Environmental Verifier\",
\"description\": \"Authority to verify ORE contracts\",
\"min_attestations\": 5,
\"validity_years\": 3,
\"reward_zen\": 10
}"
}{
"kind": 30501,
"pubkey": "<applicant_hex>",
"tags": [
["d", "<request_id>"],
["permit", "PERMIT_ORE_V1"],
["t", "uplanet"]
],
"content": "{
\"statement\": \"I have expertise in ecological validation\",
\"evidence\": \"https://ipfs.io/ipfs/Qm...\"
}"
}{
"kind": 30502,
"pubkey": "<attester_hex>",
"tags": [
["d", "<attestation_id>"],
["e", "<request_event_id>"],
["p", "<applicant_hex>"],
["permit", "PERMIT_ORE_V1"]
],
"content": "{
\"statement\": \"I attest to this applicant's competence\",
\"date\": \"2025-10-30T12:00:00Z\"
}"
}{
"kind": 30503,
"pubkey": "<UPLANETNAME_G1_hex>",
"tags": [
["d", "<credential_id>"],
["p", "<holder_hex>"],
["permit", "PERMIT_ORE_V1"]
],
"content": "{
\"@context\": \"https://www.w3.org/2018/credentials/v1\",
\"id\": \"urn:uuid:...\",
\"type\": [\"VerifiableCredential\", \"UPlanetLicense\"],
\"issuer\": \"did:nostr:<UPLANETNAME_G1_hex>\",
\"issuanceDate\": \"2025-10-30T12:00:00Z\",
\"expirationDate\": \"2028-10-30T12:00:00Z\",
\"credentialSubject\": {
\"id\": \"did:nostr:<holder_hex>\",
\"license\": \"PERMIT_ORE_V1\",
\"attestations\": 5
}
}"
}Problem: How to initialize a permit when no holders exist yet?
Solution: For a permit requiring N signatures, register N+1 MULTIPASS members on the station.
Cross-Attestation Process:
- Each member attests all other members (except themselves)
- Result: Each member receives N attestations
- Oracle issues credentials to all members simultaneously
Examples:
- PERMIT_ORE_V1 (5 signatures) → 6 members (each receives 5 attestations)
- PERMIT_DRIVER (12 signatures) → 13 members (each receives 12 attestations)
- PERMIT_WOT_DRAGON (3 signatures) → 4 members (each receives 3 attestations)
graph LR
A[User Requests] --> B[Experts Attest]
B --> C[Threshold Reached]
C --> D[Oracle Issues VC]
D --> E[VC Added to DID]
E --> F[Economic Reward]
| Permit ID | Name | Attestations | Validity | Reward |
|---|---|---|---|---|
| PERMIT_ORE_V1 | ORE Verifier | 5 | 3 years | 10 Ẑen |
| PERMIT_DRIVER | Driver's License | 12 | 15 years | 5 Ẑen |
| PERMIT_WOT_DRAGON | UPlanet Authority | 3 | Unlimited | 50 Ẑen |
| PERMIT_MEDICAL_FIRST_AID | First Aid | 8 | 2 years | 8 Ẑen |
| PERMIT_BUILDING_ARTISAN | Artisan | 10 | 5 years | 12 Ẑen |
| PERMIT_EDUCATOR_COMPAGNON | Educator | 12 | Unlimited | 15 Ẑen |
| PERMIT_FOOD_PRODUCER | Food Producer | 6 | 3 years | 8 Ẑen |
| PERMIT_MEDIATOR | Mediator | 15 | 5 years | 20 Ẑen |
The ORE System attaches environmental obligations to geographic cells (UMAP), creating a decentralized ecological registry.
| Kind | Name | Description | Signed by |
|---|---|---|---|
| 30312 | ORE Meeting Space | Persistent Geographic Space | UMAP DID |
| 30313 | ORE Verification Meeting | Verification meeting | ORE Expert |
Note: Originally used kinds 30400-30402. Migrated to 30312-30313 to avoid conflict with NIP-99 (Classified Listing uses 30402).
{
"kind": 30312,
"pubkey": "<UMAP_hex>",
"tags": [
["d", "ore-space-43.60-1.44"],
["g", "43.60,1.44"],
["room", "UMAP_ORE_43.60_1.44"],
["t", "uplanet"],
["t", "ore-space"]
],
"content": "{
\"description\": \"Persistent geographic space for ORE verifications\",
\"vdo_url\": \"https://vdo.ninja/?room=UMAP_ORE_43.60_1.44\",
\"contractId\": \"ORE-2025-001\",
\"provider\": \"did:nostr:<verifier_hex>\"
}"
}{
"kind": 30313,
"pubkey": "<expert_hex>",
"tags": [
["d", "ore-verification-43.60-1.44-1730289600"],
["a", "30312:<authority>:ore-space-43.60-1.44"],
["g", "43.60,1.44"],
["start", "1730289600"],
["permit", "PERMIT_ORE_V1"]
],
"content": "{
\"result\": \"compliant\",
\"evidence\": \"ipfs://Qm...\",
\"method\": \"satellite_imagery\",
\"notes\": \"Forest cover: 82%\"
}"
}Environmental obligations are stored in the UMAP's DID document (kind 30800):
{
"id": "did:nostr:<UMAP_hex>",
"type": "UMAPGeographicCell",
"geographicMetadata": {
"coordinates": {"lat": 43.60, "lon": 1.44}
},
"environmentalObligations": {
"oreContract": {
"contractId": "ORE-2025-001",
"description": "Maintain 80% forest cover",
"provider": "did:nostr:<verifier_hex>",
"reward": "10"
},
"verificationStatus": "verified",
"lastVerification": "2025-10-30T12:00:00Z"
}
}1. ORE Contract → UMAP DID (kind 30800)
2. ORE Meeting Space → NOSTR event (kind 30312)
3. Expert Validation → NOSTR event (kind 30313)
4. Automatic Payment → UPLANETNAME.RnD → UMAP Wallet
5. UMAP Redistribution → Local guardians/residents
| Aspect | Traditional ORE (Notarized) | UPlanet ORE (Decentralized) |
|---|---|---|
| Notary Fees | €1,500 - €3,000 | €0 |
| Legal Drafting | €2,000 - €5,000 | €0 |
| Registry | €500 - €1,000 | €0 |
| Annual Audit | €1,000 - €2,000/year | Volunteer experts |
| Verification | In-person visits | Satellite + IoT + VDO.ninja |
| Total (5 years) | €9,500 - €19,000 | ~€50 (hosting) |
Savings: 99.7% cost reduction while increasing transparency and participation.
All UPlanet events SHOULD include these tags:
["latitude", "FLOAT_STRING"]
["longitude", "FLOAT_STRING"]
["application", "UPlanet"]["did", "did:nostr:<hex_pubkey>"]
["t", "uplanet"]["permit", "PERMIT_ID"]
["e", "<related_event_id>"]
["p", "<related_pubkey>"]["d", "ore-space-{lat}-{lon}"]
["g", "{lat},{lon}"]
["room", "UMAP_ORE_{lat}_{lon}"]UPlanet relays synchronize all NIP-101 events across the constellation network.
| Category | Kinds | Description |
|---|---|---|
| Core | 0, 1, 3, 5, 6, 7 | Profiles, notes, contacts, deletions, reposts, reactions |
| Media | 21, 22 | Videos (short/long form) |
| Files | 1063 | File metadata (NIP-94) |
| Comments | 1111 | Video comments (NIP-22) |
| Content | 30023, 30024 | Articles, calendar events |
| Identity | 30800 | DID documents (NIP-101) |
| Oracle | 30500-30503 | Permits (definitions, requests, attestations, credentials) |
| ORE | 30312-30313 | Environmental obligations (meeting spaces, verification meetings) |
Total: 20 event types synchronized automatically
# Automatic daily synchronization (via _12345.sh)
./backfill_constellation.sh --days 1
# Manual full sync
./backfill_constellation.sh --days 7 --verbose
# View constellation statistics
./backfill_constellation.sh --stats[2025-11-06 12:35:12] [INFO] SYNC_STATS:
events=1523
dms=45
public=1478
deletions=12
videos=8
files=15
comments=34
did=34
oracle=23
ore=15
- IPNS Swarm Scan →
~/.zen/tmp/swarm/*/12345.json - Extract Relay URLs →
myRELAYfield - HEX Pubkey Collection →
~/.zen/game/nostr/*/HEX - WebSocket Backfill → Direct or via P2P tunnels
- Strfry Import → Local database update
All UPlanet API operations require NIP-42 authentication.
- Client generates auth event (kind 22242)
- Client sends auth event to relay
- Server queries relay for recent auth event
- Server verifies signature and challenge
- Server authorizes request
{
"kind": 22242,
"pubkey": "<user_hex>",
"tags": [
["relay", "ws://127.0.0.1:7777"],
["challenge", "<random_challenge>"]
],
"content": "",
"created_at": 1730289600
}# User authenticates via NOSTR
curl -X POST https://api.example.com/api/permit/request \
-H "X-Nostr-Auth: <auth_event_id>" \
-d '{"permit_type": "PERMIT_ORE_V1"}'From a single seed, generate:
- NOSTR keypair (identity)
- IPFS key (storage)
- Ğ1 wallet (economy)
- Bitcoin address (interoperability)
Private keys are split into 3 fragments:
- Fragment 1 → Local storage
- Fragment 2 → IPFS encrypted backup
- Fragment 3 → Trusted guardian
Reconstitution: Any 2 fragments can restore the full private key.
~/.zen/game/nostr/<EMAIL>/
├── .secret.nostr # NOSTR private key
├── HEX # NOSTR public key (hex)
├── NPUBcopyright.png # QR code (npub)
├── GPGPASS # Encryption password
├── .ssss/ # Shamir fragments
│ ├── fragment_1.txt
│ ├── fragment_2.txt.gpg
│ └── fragment_3.txt.gpg
└── APP/ # IPFS drive
Scenario: Alice posts from her neighborhood UMAP.
{
"kind": 1,
"pubkey": "<alice_hex>",
"tags": [
["p", "<UMAP_hex>"],
["latitude", "43.6047"],
["longitude", "1.4442"],
["application", "UPlanet"]
],
"content": "Community garden meeting tomorrow at 10am!"
}Bob, subscribed to that UMAP's npub, sees the message instantly.
Scenario: Carol wants to become an ORE verifier.
graph TB
A[Carol creates MULTIPASS] --> B[Carol requests PERMIT_ORE_V1]
B --> C[5 experts attest Carol's competence]
C --> D[Oracle issues VC to Carol]
D --> E[VC added to Carol's DID]
E --> F[Carol receives 10 Ẑen reward]
F --> G[Carol can now validate ORE contracts]
API Flow:
# 1. Carol requests permit
POST /api/permit/request
{
"permit_type": "PERMIT_ORE_V1",
"statement": "I have ecological expertise",
"evidence": "ipfs://Qm..."
}
# 2. Experts attest (5 times)
POST /api/permit/attest
{
"request_id": "req_123",
"statement": "I attest to Carol's competence"
}
# 3. Oracle auto-issues VC (when threshold reached)
# 4. Carol's DID updated with new credential
# 5. Carol receives economic rewardScenario: Dave's UMAP commits to maintaining forest cover.
{
"kind": 30312,
"pubkey": "<UMAP_hex>",
"tags": [
["d", "ore-space-48.85--2.34"],
["g", "48.85,-2.34"],
["room", "UMAP_ORE_48.85_-2.34"]
],
"content": "{
\"description\": \"Persistent ORE meeting space for UMAP\",
\"contractId\": \"ORE-2025-DAVE-001\",
\"provider\": \"did:nostr:<carol_hex>\"
}"
}Annual Verification:
- Carol (certified ORE expert) validates via satellite imagery
- Carol publishes verification meeting event (kind 30313)
- System automatically triggers 10 Ẑen payment to Dave's UMAP
- Dave redistributes to local guardians
Economic Incentive: Dave's UMAP earns 50 Ẑen over 5 years for maintaining forest.
Scenario: Automated service publishes weather alerts for REGION Paris.
{
"kind": 1,
"pubkey": "<REGION_PARIS_hex>",
"tags": [
["latitude", "48.8534"],
["longitude", "2.3488"],
["application", "UPlanet"],
["t", "weather-alert"]
],
"content": "⚠️ Storm warning: Heavy rainfall expected 18:00-22:00"
}All users subscribed to the Paris REGION GeoKey receive the alert.
Scenario: Alice has a permit from Station A, visits Station B.
graph LR
A[Station A issues permit to Alice] --> B[Event 30503 published to NOSTR]
B --> C[Station B backfills from constellation]
C --> D[Station B recognizes Alice's permit]
D --> E[Alice can attest on both stations]
Result: Decentralized permit recognition across the entire UPlanet network.
- Risk: Publishing precise coordinates reveals location
- Mitigation:
- Use broader grid levels (SECTOR, REGION) for privacy
- Implement selective disclosure (only trusted contacts see precise location)
- Client-side filtering of location data
- Risk: Frequent geo-tagged posts enable movement tracking
- Mitigation:
- Rotate nyms (secondary keys) for location-based posts
- Use GeoKey as location identity instead of personal key
- Implement ephemeral location tags
- Risk: Compromise of
UPLANETNAMEdisrupts entire system - Mitigation:
- Store
UPLANETNAMEin secure IPFS swarm key - Distribute only to trusted constellation members
- Implement key rotation procedures
- Store
- Risk: Fake attestations or credential forgery
- Mitigation:
- All events cryptographically signed (Schnorr)
- Verify attester holds valid permit before accepting attestation
- Oracle validates entire attestation chain before issuing VC
- Multi-signature requirement (no single point of trust)
- Risk: Single entity creates multiple fake identities to self-attest
- Mitigation:
- Require attesters to be in Ğ1 Web of Trust (verified humans)
- Bootstrap requires real MULTIPASS registrations
- Economic cost (Ẑen) for permit applications
- Risk: Authority key (
UPLANETNAME.G1) could issue fraudulent permits - Mitigation:
- Authority key held by cooperative governance (multi-sig)
- All issued permits are public and auditable on NOSTR
- Community can reject malicious credentials
- Economic incentives aligned with honest behavior
- ✅ Uses standard event kinds where possible (0, 1, 3, etc.)
- ✅ Follows NIP-01 (Basic protocol)
- ✅ Implements NIP-10 (
eandptags) - ✅ Implements NIP-33 (Parameterized Replaceable Events)
- ✅ Implements NIP-42 (Authentication)
- ✅ Compatible with existing Nostr clients (with extensions)
- ✅ DIDs follow W3C DID Core Specification
- ✅ Verifiable Credentials follow W3C VC Data Model
- ✅ Signature format compatible with
Ed25519VerificationKey2020
- ✅ Ğ1 wallet integration (Duniter)
- ✅ Bitcoin address derivation
- ✅ Future: Ethereum address support
- NIP-01: Basic protocol flow
- NIP-07: Browser extensions
- NIP-10: Conventions for
eandptags - NIP-11: Relay information
- NIP-33: Parameterized Replaceable Events
- NIP-42: Authentication
- Main Repository: github.com/papiche/Astroport.ONE
- NIP-101 Repository: github.com/papiche/NIP-101
- Oracle System: docs/ORACLE_SYSTEM.md
- ORE System: docs/ORE_SYSTEM.md
- DID Implementation: DID_IMPLEMENTATION.md
- Public Portal: copylaradio.com
- libsodium: Cryptographic library
- strfry: High-performance Nostr relay
- Duniter: Ğ1 libre currency implementation
- Web of Trust for Driver's License (French)
- Environmental Real Obligations (ORE) (French legal framework)
- Hierarchical GeoKeys (UMAP, SECTOR, REGION)
- DID documents on NOSTR (kind 30800 - NIP-101)
- Oracle permit system (kinds 30500-30503)
- ORE environmental contracts (kinds 30312-30313)
- Constellation synchronization (backfill)
- NIP-42 authentication
- Web interface (
/oracle) - API routes (FastAPI)
- Twin-Key derivation (NOSTR, IPFS, Ğ1, Bitcoin)
- Mobile client integration
- Advanced ORE verification (satellite imagery)
- VDO.ninja integration for live validation
- Multi-language support
- Reputation system for attesters
- Dispute resolution mechanism
- Cross-chain bridge (Ethereum)
- Anonymous credentials (zero-knowledge proofs)
- Geographic privacy modes
We invite the Nostr community to review and provide feedback on NIP-101.
- Event Kind Allocation: Are kinds 30500-30503 (Oracle), 30312-30313 (ORE), and 30800 (DID) acceptable?
- DID Integration: We've chosen kind 30800 to avoid conflict with NIP-53 (Live Event using 30311). Is this acceptable?
- Geographic Tags: Are
latitude/longitudetags sufficient, or should we use GeoJSON? - Constellation Sync: Should backfill be standardized across all Nostr implementations?
- Economic Layer: How to integrate Ğ1/Ẑen payments with other Nostr economic systems?
- GitHub Issues: github.com/papiche/NIP-101/issues
- Pull Requests: Improvements to spec or implementation
- Discussions: github.com/papiche/NIP-101/discussions
- Testing: Deploy a UPlanet station and report feedback
This specification is released under AGPL-3.0.
Implementation code is available at:
- Astroport.ONE (AGPL-3.0)
- NIP-101 (AGPL-3.0)
Lead Developers:
- papiche - UPlanet & Astroport.ONE architecture
- CopyLaRadio SCIC - Cooperative governance and economic design
Contributors:
- Astroport.ONE community
- Ğ1 libre currency community
- NOSTR protocol community
Special Thanks:
- hoytech - strfry Nostr relay
- fiatjaf - Nostr protocol creator
- Duniter community - Ğ1 blockchain implementation
🌍 NIP-101: Decentralized Identity, Geographic Coordination & Ecological Accountability on NOSTR
Built by the community, for the community 🤝