04. NCrypt

Encrypted Messaging

NCrypt ("NC" or "nc") provides end-to-end encrypted messaging with blockchain-anchored message delivery and optional read receipts.

Overview

Purpose: Send and receive encrypted messages with verifiable delivery and read status.

Key Features:

  • End-to-end encryption using ChaCha20-Poly1305

  • X25519 key exchange

  • On-chain message delivery for verifiability

  • Read receipts with cryptographic proof

  • File attachments

  • Thread-based conversation view

Location: src/packages/ncrypt/

Encryption Details:

  • Algorithm: ChaCha20-Poly1305 (AEAD - Authenticated Encryption with Associated Data)

  • Key Exchange: X25519 (Curve25519 for Diffie-Hellman)

  • Message ID: 8-byte random or SHA-256 hash

  • Key Storage: LocalStorage (format: ncrypt_private_key_{encodedAddress})


Encryption Setup

Generate Encryption Keys

Before sending/receiving encrypted messages, users must generate and publish their X25519 key pair.

Implementation:

Blockchain Extrinsic: api.tx.postman.publishKey()

Parameters:

  • keyPayload: X25519 public key (32 bytes)

Implementation:

Storage Location:

  • Private Key: localStorage.ncrypt_private_key_{address}

  • Public Key: On-chain via postman.keys() query


Retrieve Public Key

Fetch another user's published X25519 public key from the blockchain.

Blockchain Query: api.query.postman.keys()

Parameters:

  • encodedAddress: SS58-355 encoded Gen6 address

Implementation:

Usage:


Query Read Receipts

Check if messages have been read by querying the blockchain inbox.

Blockchain Query: api.query.postman.inbox()

Parameters:

  • recipientAddress: SS58-355 encoded recipient address

  • senderAddress: SS58-355 encoded sender address

Implementation:

Response: Array of read receipt data

Purpose: Provides cryptographic proof that messages have been read by the recipient, enabling read receipts functionality.


Messaging API

Send Message

Create and send an encrypted message.

Endpoint: POST /ncrypt/messages

Authentication: Required (JWT)

Request:

Request Body:

Response:

Encryption Process:

Important: Messages are encrypted twice:

  1. encrypted_content_for_recipient - Recipient can decrypt

  2. encrypted_content_for_sender - Sender can decrypt (for message history)


Blockchain Message Delivery

For verifiable delivery, messages can be sent on-chain.

Blockchain Extrinsic: api.tx.postman.sendMessage()

Parameters:

  • recipientAddress: SS58-355 encoded address

  • messagePayload: Encrypted message payload

  • trackingHash (optional): SHA-256 hash for tracking

Implementation:

Complete Send Flow:


Get Message Threads

Retrieve a paginated list of message threads (conversations).

Endpoint: GET /ncrypt/threads

Authentication: Required (JWT)

Query Parameters:

  • page (optional): Page number (default: 1)

  • page_size (optional): Items per page (default: 20)

Implementation:

Response:

Example Response:

Usage:


Get Messages in Thread

Retrieve messages in a specific conversation.

Endpoint: GET /ncrypt/threads/{peer_address}

Authentication: Required (JWT)

Parameters:

  • peer_address (path): Gen6 address of conversation partner

  • page (query): Page number

  • page_size (query): Items per page

Implementation:

Response:

Decryption:

Decryption Implementation:


Mark Thread as Read

Mark all messages in a thread as read.

Endpoint: PATCH /ncrypt/threads/{peer_address}/read

Authentication: Required (JWT)

Parameters:

  • peer_address (path): Peer Gen6 address

Implementation:

Response: Updated thread with unread_count: 0

Usage:


Delete Thread

Delete an entire conversation thread.

Endpoint: DELETE /ncrypt/threads/{peer_address}

Authentication: Required (JWT)

Parameters:

  • peer_address (path): Peer Gen6 address

Implementation:

Response: 204 No Content

Warning: This permanently deletes all messages in the thread.


Attachments

Upload Attachment

Upload a file to attach to messages.

Endpoint: POST /ncrypt/attachments

Authentication: Required (JWT)

Request:

Response:

Usage Flow:


Read Receipts

Request Read Proof

Request cryptographic proof that a message was read.

Blockchain Extrinsic: api.tx.postman.requestPassphrase()

Parameters:

  • senderAddress: Message sender address

  • messagePayload: Original encrypted message

Implementation:

Usage:

Note: Read receipts only work for messages sent on-chain (on_chain_message_id must be set).


Query Keys

TanStack Query Keys:


Best Practices

  1. Generate keys on first use - Prompt users to enable encryption

  2. Check recipient has keys - Verify before allowing message send

  3. Backup private keys - Provide export/import functionality


Next Steps

  • Parking - Stake tokens for validator rewards

  • Finance - Transfer tokens

Last updated

Was this helpful?