Nostr. Event. GiftWrap
(Nostr Lib v0.2.1)
(event)
(nip59)
View Source
Gift Wrap event (kind 1059)
A gift wrap event wraps any other event (typically a seal). It uses a random, one-time-use
keypair for signing, which obscures the original author's identity. The recipient is identified
by a p tag.
Gift wrapping provides the outermost layer of privacy in NIP-59's three-layer protocol:
- Rumor: unsigned event (deniable)
- Seal: encrypted rumor, signed by author
- Gift Wrap: encrypted seal, signed with ephemeral key
Defined in NIP 59 https://github.com/nostr-protocol/nips/blob/master/59.md
Summary
Functions
Create a gift wrap from a seal
Parse a kind 1059 event into a GiftWrap struct
Unwrap a gift wrap to extract the seal
Unwrap a gift wrap to extract the original rumor
Wrap a message in a complete gift wrap (rumor → seal → gift wrap)
Types
@type t() :: %Nostr.Event.GiftWrap{ encrypted_seal: binary(), event: Nostr.Event.t(), recipient: binary() }
Gift wrap event containing an encrypted seal
Functions
@spec create(Nostr.Event.Seal.t(), binary(), Keyword.t()) :: t()
Create a gift wrap from a seal
Encrypts the seal using NIP-44 with a random ephemeral key and the recipient's public key. The gift wrap is signed by the ephemeral key.
Parameters
- seal: The seal to wrap
- recipient_pubkey: Recipient's public key (hex-encoded)
- opts: Optional keyword list:
- :created_at - override random timestamp
- :ephemeral_seckey - use specific ephemeral key (for testing)
Example
gift_wrap = GiftWrap.create(seal, recipient_pubkey)
@spec parse(Nostr.Event.t()) :: t() | {:error, String.t(), Nostr.Event.t()}
Parse a kind 1059 event into a GiftWrap struct
Note: This only extracts the encrypted content. Use unwrap/2 to decrypt the seal.
@spec unwrap(t(), binary()) :: {:ok, Nostr.Event.Seal.t()} | {:error, atom()}
Unwrap a gift wrap to extract the seal
Decrypts the gift wrap's content using the recipient's secret key. The ephemeral public key is obtained from the gift wrap event.
Parameters
- gift_wrap: The gift wrap to unwrap
- recipient_seckey: Recipient's secret key (hex-encoded)
Returns
{:ok, seal}on success{:error, reason}on failure
@spec unwrap_message(t(), binary()) :: {:ok, Nostr.Event.Rumor.t()} | {:error, atom()}
Unwrap a gift wrap to extract the original rumor
This is a convenience function that decrypts all layers:
- Unwraps the gift wrap to get the seal
- Unwraps the seal to get the rumor
Parameters
- gift_wrap: The gift wrap to unwrap
- recipient_seckey: Recipient's secret key (hex-encoded)
Returns
{:ok, rumor}on success{:error, reason}on failure
Example
{:ok, rumor} = GiftWrap.unwrap_message(gift_wrap, recipient_seckey)
IO.puts(rumor.content)
Wrap a message in a complete gift wrap (rumor → seal → gift wrap)
This is a convenience function that performs all three steps of the NIP-59 protocol:
- Creates an unsigned rumor from the message
- Seals the rumor with the sender's key
- Wraps the seal with an ephemeral key
Parameters
- kind: The event kind for the inner rumor
- content: The message content
- sender_seckey: Sender's secret key (hex-encoded)
- recipient_pubkey: Recipient's public key (hex-encoded)
- opts: Optional keyword list:
- :tags - tags for the inner rumor (default: [])
- :created_at - timestamp for the rumor (default: now)
Example
gift_wrap = GiftWrap.wrap_message(1, "Hello!", sender_seckey, recipient_pubkey)