NAP-COMMON / PR #67
Common Social Actions
Full specification from the fetched upstream revision ↗. The document below is rendered from its original Markdown. Follow the latest source on GitHub ↗.
NAP-COMMON
Common Social Actions
draft
NAP ID: NAP-COMMON
Domain: common
Depends:
identity— capability · required — user-authoritative actions use the current shell-user identity as the event author.relay— capability · required — fetches kind 0 profiles and publishes kind 3 follow lists, kind 7 reactions, and kind 1984 reports.relay— wire · required — importsRelayEventResultfor raw profile event returns.resource— wire · optional — importedRelayEventResult.sidecar.resources?carriesResourceSidecarEntry[], a type owned by theresourcedomain. Web binding (NIP-5D):window.napplet.common; domain presence signals availability.
Description
NAP-COMMON is a small shell-mediated surface for public Nostr identifier helpers, profile lookup, and common social actions. It does not expose generic event construction, relay selection, moderation policy, or private-key material.
The napplet supplies intent and minimal targets. The shell owns user identity, consent, signing, replacement-list merging, publishing, lookup policy, and NIP normalization.
API Surface
| Operation | Parameters | Result | Wire |
|---|---|---|---|
encodeNip19 |
input (CommonNip19EncodeInput) |
CommonNip19EncodeResult |
common.encodeNip19 / .result |
decodeNip19 |
value (tstr) |
CommonNip19DecodeResult |
common.decodeNip19 / .result |
getProfile |
target (CommonProfileTarget) |
CommonProfileResult |
common.getProfile / .result |
follows |
none | [ * HexPubkey ] |
common.follows / .result |
follow |
one or more npub targets |
CommonActionResult |
common.follow / .result |
unfollow |
one or more npub targets |
CommonActionResult |
common.unfollow / .result |
react |
id, reaction, customEmojiHref? |
CommonActionResult |
common.react / .result |
report |
target, reason, text |
CommonActionResult |
common.report / .result |
Schemas
RelayEventResult is owned by NAP-RELAY. NAP-COMMON imports it by name for
raw kind 0 profile events returned by getProfile. Shell-created action events
remain plain NostrEvent values because they are not relay-read results.
Primitive aliases:
| Name | Definition |
|---|---|
Npub |
NIP-19 npub string |
Nprofile |
NIP-19 nprofile string |
HexPubkey |
32-byte public key encoded as lowercase hex |
NostrEventId |
32-byte event id encoded as lowercase hex |
NostrEvent |
Nostr event object |
CommonPubkeyList |
non-empty list of Npub values |
CommonProfileTarget |
HexPubkey, Npub, or Nprofile |
RelayEventResult |
external type owned by NAP-RELAY |
Enums:
| Name | Values |
|---|---|
CommonNip19Type |
npub, note, nprofile, nevent, naddr, nrelay |
CommonReaction |
+, -, or text |
CommonReportReason |
nudity, malware, profanity, illegal, spam, impersonation, other |
CommonNip19EncodeInput variants:
| Variant | Required fields | Optional fields |
|---|---|---|
npub |
type: "npub", hex: tstr |
none |
note |
type: "note", hex: tstr |
none |
nprofile |
type: "nprofile", pubkey: HexPubkey |
relays: list of tstr |
nevent |
type: "nevent", eventId: NostrEventId |
relays: list of tstr, author: HexPubkey, kind: uint |
naddr |
type: "naddr", identifier: tstr, pubkey: HexPubkey, kind: uint |
relays: list of tstr |
nrelay |
type: "nrelay", relay: tstr |
none |
CommonNip19EncodeResult fields:
| Field | Required | Type |
|---|---|---|
ok |
yes | boolean |
value |
no | text |
nip19Type |
no | CommonNip19Type |
error |
no | text |
CommonNip19DecodeResult fields:
| Field | Required | Type |
|---|---|---|
ok |
yes | boolean |
nip19Type |
no | CommonNip19Type |
hex |
no | text |
pubkey |
no | HexPubkey |
eventId |
no | NostrEventId |
identifier |
no | text |
relays |
no | list of text |
author |
no | HexPubkey |
kind |
no | unsigned integer |
relay |
no | text |
error |
no | text |
CommonProfileData fields:
| Field | Required | Type |
|---|---|---|
name |
no | text |
displayName |
no | text |
about |
no | text |
picture |
no | text |
banner |
no | text |
nip05 |
no | text |
lud16 |
no | text |
website |
no | text |
| additional fields | no | any |
CommonProfileResult fields:
| Field | Required | Type |
|---|---|---|
ok |
yes | boolean |
pubkey |
yes | HexPubkey |
profile |
no | CommonProfileData or null |
result |
no | RelayEventResult |
error |
no | text |
CommonActionResult fields:
| Field | Required | Type |
|---|---|---|
ok |
yes | boolean |
eventId |
no | text |
event |
no | NostrEvent |
error |
no | text |
CommonReportTarget variants:
| Variant | Required fields | Optional fields |
|---|---|---|
| event | type: "event", id: tstr |
pubkey: tstr, relay: tstr |
| pubkey | type: "pubkey", pubkey: Npub or HexPubkey |
relay: tstr |
Operation Rules
| Operation | Rules |
|---|---|
encodeNip19 |
Encodes public NIP-19 identifiers: npub, note, nprofile, nevent, naddr, nrelay. MUST reject nsec. |
decodeNip19 |
Decodes the same public types. MUST reject nsec, ignore unknown TLVs, and SHOULD reject strings longer than 5000 chars. |
getProfile |
Accepts hex pubkey, npub, or nprofile. Normalizes to hex, treats nprofile relay TLVs as hints, queries latest kind 0, returns the raw profile event as RelayEventResult, and returns profile: null if not found. |
follows |
Returns hex pubkeys from the shell-user's current NIP-02 kind 3 follow list. Returns an empty array when no list is found. |
follow |
Decodes each npub, merges new p tags into the current NIP-02 kind 3 list, preserves unrelated tags, signs, publishes. Idempotent. |
unfollow |
Decodes each npub, removes matching p tags from the current kind 3 list, preserves unrelated tags, signs, publishes. Idempotent. |
react |
Publishes NIP-25 kind 7 for native Nostr events only. reaction is +, -, one Unicode emoji, or one NIP-30 shortcode. customEmojiHref requires one matching emoji tag. |
report |
Publishes NIP-56 kind 1984. Pubkey reports use p with reason. Event reports use e with reason plus author p; shell MUST resolve or reject missing authors. |
SDKs MAY expose report(id|pubkey, reason, text) shorthand, but wire messages
MUST use CommonReportTarget.
NIP Mapping
| Operation | NIP |
|---|---|
encodeNip19, decodeNip19 |
NIP-19 public bech32 / TLV identifiers |
getProfile |
NIP-01 latest kind 0 by pubkey |
follows, follow, unfollow |
NIP-02 replacement kind 3 follow list |
react |
NIP-25 kind 7; optional NIP-30 emoji tag |
report |
NIP-56 kind 1984 |
Wire Protocol
common.* messages use NIP-5D wire format: { "type": "domain.action", ...payload }.
| Type | Direction | Payload fields |
|---|---|---|
common.encodeNip19 |
napplet -> shell | id, input |
common.encodeNip19.result |
shell -> napplet | id, ok, value?, nip19Type?, error? |
common.decodeNip19 |
napplet -> shell | id, value |
common.decodeNip19.result |
shell -> napplet | id, ok, nip19Type?, hex?, pubkey?, eventId?, identifier?, relays?, author?, kind?, relay?, error? |
common.getProfile |
napplet -> shell | id, target |
common.getProfile.result |
shell -> napplet | id, ok, pubkey, profile?, result?, error? |
common.follows |
napplet -> shell | id |
common.follows.result |
shell -> napplet | id, ok, pubkeys, error? |
common.follow |
napplet -> shell | id, pubkeys |
common.follow.result |
shell -> napplet | id, ok, eventId?, event?, error? |
common.unfollow |
napplet -> shell | id, pubkeys |
common.unfollow.result |
shell -> napplet | id, ok, eventId?, event?, error? |
common.react |
napplet -> shell | id, targetEventId, reaction, customEmojiHref? |
common.react.result |
shell -> napplet | id, ok, eventId?, event?, error? |
common.report |
napplet -> shell | id, target, reason, text |
common.report.result |
shell -> napplet | id, ok, eventId?, event?, error? |
Error Handling
Result messages use ok: false plus error. Common errors:
"not-signed-in", "invalid-pubkey", "invalid-nip19",
"unsupported-nip19-type", "invalid-profile-target", "invalid-target",
"invalid-reaction", "invalid-report-reason", "author-unresolved",
"user-denied", "relay-timeout", "publish-failed", "unsupported".
Shell Behavior
- MUST reject NIP-19 helper requests that encode or decode
nsec. - MUST normalize NIP-19 helper results to hex fields for keys and event ids.
- MUST resolve
getProfiletargets to hex before querying relays. - MUST query kind 0 replaceable metadata for
getProfile. - SHOULD merge observed profile-event relay URLs into
RelayEventResult.sidecar.relayHintswhen the shell can disclose them. - MAY include pre-resolved profile image resources in
RelayEventResult.sidecar.resources; NAP-RELAY's default-off sidecar privacy policy and NAP-RESOURCE's fetch policy both apply. - MUST return hex pubkeys from
follows. - MUST perform all signing and never expose signing keys.
- MUST reject modifying operations when no shell-user signer is connected;
getProfileMAY work signed out. - MUST publish follow changes as NIP-02 replacement kind 3 events.
- MUST publish reactions as kind 7 events for native Nostr event targets.
- MUST publish reports as kind 1984 events with NIP-56 reasons.
- MAY prompt, rate-limit, deny, redact, or route by runtime policy.
Security Considerations
- Treat NIP-19 values, relay hints, report text, custom emoji URLs, and profile metadata as untrusted.
- Treat
nprofilerelays as advisory; napplets can choose hostile relays. - Prompts SHOULD show requesting napplet, action, stable targets, and report text.
- Success means the shell published or returned data. It does not prove relay, client, or user acceptance.
References
- NIP-01 — Basic protocol flow and kind 0 metadata
- NIP-02 — Follow List
- NIP-19 — bech32-encoded entities
- NIP-25 — Reactions
- NIP-30 — Custom Emoji
- NIP-56 — Reporting
Implementations
- None yet.
Changelog
a189372- Introduced NAP-COMMON for shared social actions.8171616- Added profile lookup to the common social action surface.e0b1414- Added NIP-19 encode and decode helpers.f0cf652- Renamed NIP-19 result payloadtypetonip19Typeto avoid NIP-5D envelope collisions.c52def9- Added current-follow lookup to the common social action surface.7973802- Changed common profile reads to use relay-owned result shape and declared the relay dependency.77ea325- Adopted injected-domain availability and linked the current upstream web binding.