#
Nostr Mail Bridges
#
Overview
Bridges act as gateways between Nostr and legacy email infrastructure, enabling Nostr users to send/receive emails to/from recipients who are not on Nostr.
#
Sending Emails to Bridges
#
Kind 1301 Event Structure
Emails destined for non-Nostr recipients are sent with additional routing tags:
{
"kind": 1301,
"pubkey": "<sender_pubkey>",
"tags": [
["email-id", "<unique_id>"],
["mail-from", "<sender_email>"],
["rcpt-to", "<recipient_email>"]
],
"content": "<RFC 2822 email>"
}
#
Delivery Flow
- Sender creates kind 1301 event with
email-id,mail-fromandrcpt-totags - Sender gift wraps the event (NIP-59)
- Sender sends to bridge's DMs relays
- Bridge receives and unwraps the gift wrap
- Bridge extracts
email-idand SMTP routing information from tags - Bridge delivers email via SMTP
- Bridge sends DSN (Delivery Status Notification) back to sender
#
Tags
#
Example
{
"kind": 1301,
"pubkey": "alice_pubkey",
"tags": [
["email-id", "550e8400-e29b-41d4-a716-446655440000"],
["mail-from", "npub1alice...@bridge.com"],
["rcpt-to", "bob@example.com"]
],
"content": "From: npub1alice...@bridge.com\nTo: bob@example.com\nSubject: Hello\nDate: Sat, 28 Dec 2024 12:00:00 +0000\n\nHey Bob, how are you?"
}
#
Delivery Status Notifications (DSN)
Bridges send delivery status notifications to inform senders about the outcome of email delivery attempts.
#
Kind 7679: Delivery Status Notification
The DSN event allows senders to track whether their emails were successfully delivered and, if not, understand why delivery failed.
#
Privacy Design
To protect user privacy, DSNs implement forward secrecy at the bridge level:
- No p tag: Recipient metadata is not exposed on public relays
- Ephemeral encryption: Content is encrypted with a temporary key that the bridge immediately destroys
- Permanent signature: Event is signed with bridge's permanent key for authenticity
This means:
- Public relays cannot see who the original sender was (no p tag)
- Bridge cannot decrypt its own archived DSN events (temporary key destroyed)
- DSN authenticity is still verifiable via bridge's permanent signature
#
Event Structure
{
"kind": 7679,
"pubkey": "<bridge_permanent_pubkey>",
"tags": [
["r", "<email_id>"],
["ephemeral-pubkey", "<temp_pubkey>"]
],
"content": "<nip44_encrypted_content>"
}
#
Tags
#
Status Values
#
Content (Encrypted)
The content field contains JSON data encrypted with NIP-44 using a temporary ephemeral key.
{
"status": "delivered",
"recipient": "bob@example.com",
"smtp_code": 250,
"smtp_response": "2.1.5 OK",
"attempted_at": 1735401600,
"delivered_at": 1735401605,
"details": "Email successfully delivered to recipient's SMTP server"
}
#
Content Fields
#
Example: Successful Delivery
{
"kind": 7679,
"pubkey": "bridge_permanent_pubkey",
"tags": [
["r", "550e8400-e29b-41d4-a716-446655440000"],
["ephemeral-pubkey", "a7b3c9d2..."]
],
"content": "<nip44_encrypted: {\"status\":\"delivered\",\"recipient\":\"bob@example.com\",\"smtp_code\":250,\"smtp_response\":\"2.1.5 OK\",\"attempted_at\":1735401600,\"delivered_at\":1735401605,\"details\":\"Email successfully delivered\"}>"
}
#
Example: Failed Delivery
{
"kind": 7679,
"pubkey": "bridge_permanent_pubkey",
"tags": [
["r", "550e8400-e29b-41d4-a716-446655440000"],
["ephemeral-pubkey", "e8d4f1a6..."]
],
"content": "<nip44_encrypted: {\"status\":\"failed\",\"recipient\":\"bob@example.com\",\"smtp_code\":550,\"smtp_response\":\"5.1.1 The email account that you tried to reach does not exist\",\"attempted_at\":1735401600,\"failed_at\":1735401600,\"details\":\"Recipient address rejected\"}>"
}
#
Encryption Mechanism
#
Bridge Side (Sending DSN)
- Generate ephemeral keypair:
temp_privkey+temp_pubkey - Encrypt content with NIP-44 using
(temp_privkey, sender_pubkey) - Create kind 7679 event with:
pubkey = bridge_permanent_pubkey- Sign with
bridge_permanent_privkey - Tag
["r", email_id]whereemail_idis from the original kind 1301'semail-idtag - Tag
["ephemeral-pubkey", temp_pubkey] - Encrypted content from step 2
- Immediately destroy
temp_privkey(delete from memory, never write to disk) - Publish event to relays
#
Sender Side (Receiving DSN)
Listen for events matching filter:
{ "authors": ["<bridge_pubkey>"], "kinds": [7679], "#r": ["<email_id>"] }where
<email_id>is the value from the kind 1301'semail-idtag- Extract
temp_pubkeyfromephemeral-pubkeytag - Decrypt content with NIP-44 using
(sender_privkey, temp_pubkey) - Parse decrypted JSON content
#
Security Properties
#
Retry Logic
#
Bridges SHOULD retry failed deliveries according to SMTP standards:
- 4xx errors: Retry with exponential backoff (typically 1m, 5m, 15m, 1h, 4h, 16h)
- 5xx errors: Do not retry (permanent failure, send DSN with
status: "failed")
#
Bridge MUST send DSN when:
- Success: Email delivered → DSN with
status: "delivered" - Permanent failure: 5xx error after all retries exhausted → DSN with
status: "failed" - Temporary delay: 4xx error or queued → DSN with
status: "delayed"orstatus: "queued"
#
Bridge MAY send intermediate DSNs:
For long delays (e.g., greylisting), bridge MAY send intermediate DSNs with status delayed to keep sender informed before final delivery or failure.