# Durian Chat

## 💬 Chat — On-Chain Direct Messages

> **Every message. Every wallet. Permanent. Uncensorable. Yours.**

### What It Is

**Durian Chat** is a smart-contract-backed direct messaging layer. You send a message to any address; the message body lives inside a blockchain event; the recipient (or anyone) can reconstruct the conversation by querying event logs.

* **No server.** No backend. No moderation database.
* **No account sign-up.** Your wallet *is* your identity.
* **No deletion.** On-chain events are permanent.
* **No middleware censorship.** Anyone running a KUB node can read every message.

**Contract:** `DurianSocial_V1_2.sol`

### How It Works

#### Sending a Message

```solidity
sendMessage(
  address to,        // recipient wallet
  string  content,   // up to 500 bytes, free-form
  uint256 replyTo    // optional: message ID you're replying to (0 = root)
) payable
```

**Fee:** `messageFee` (adjustable 0.001 – 0.4 KUB, default **0.02 KUB**)

#### Event Emitted

```solidity
event Message(
  address indexed from,
  address indexed to,
  uint256 indexed id,
  string  content,
  uint256 replyTo,
  uint64  timestamp
);
```

Three indexed fields (`from`, `to`, `id`) let clients filter conversations efficiently:

```javascript
// All messages between Alice and Bob
const filter1 = contract.filters.Message(alice, bob);
const filter2 = contract.filters.Message(bob, alice);
const messages = [
  ...await contract.queryFilter(filter1),
  ...await contract.queryFilter(filter2),
].sort((a, b) => Number(a.args.timestamp - b.args.timestamp));
```

### Threading

The `replyTo` parameter lets clients render **message threads**:

```
#42 Alice → Bob: "Want to trade 100 USDT for 250 KUB?"         [replyTo=0]
#43  Bob → Alice: "Yeah — send the OTC offer"                  [replyTo=42]
#44 Alice → Bob: "Done, see OTC #17"                           [replyTo=42]
```

Clients render `#43` and `#44` indented under `#42`. Purely a UI convention — the chain doesn't enforce threading structure.

### Content Rules

| Rule             | Value                                               | Enforcement             |
| ---------------- | --------------------------------------------------- | ----------------------- |
| Max message size | **500 bytes**                                       | `require` in contract   |
| Encoding         | UTF-8 string                                        | Caller's responsibility |
| Format           | Free-form text / emoji / JSON / anything ≤500 bytes | —                       |

500 bytes ≈ 2 tweets. Enough for a conversation, not enough to use chat as bulk data storage.

### Why Pay a Fee?

The per-message fee (0.02 KUB default) exists for **spam resistance**. Without it, a troll could flood every wallet on the network with garbage for pennies. With it, the economics of spam become unfavorable fast.

The fee goes **100% to the Durian Treasury** — which funds:

* Ongoing audit work
* Frontend infrastructure
* Community grants

### Governance

The `DurianSocial_V1_2` contract is minimally-governed:

| Function                          | Who   | Bounds                                |
| --------------------------------- | ----- | ------------------------------------- |
| `setFees(messageFee, requestFee)` | Owner | Both fees: 0.001–0.4 KUB              |
| `pause()` / `unpause()`           | Owner | Users still retain cancel-type rights |
| `setTreasury(address)`            | Owner | Where fees are routed                 |
| `transferOwnership(address)`      | Owner | 2-step (transfer pending → accept)    |

**Immutable caps** (cannot be raised even by owner):

* `FEE_MIN = 0.001 KUB`
* `FEE_MAX = 0.4 KUB`
* `MAX_CONTENT = 500 bytes`

### Frontend Rendering

The **Durian Wallet** and Durianfun app both include chat UI:

* **Address book:** recent counterparties, pinned favorites
* **Threaded view:** messages grouped by `replyTo`
* **Live subscription:** new messages via `contract.on("Message", ...)`
* **Token-gated channels:** (coming) pair chat with ownership of a specific Durianfun token

### Security Highlights (V1.2 Fix)

**\[M3] Balance-Delta Guard** *(March 2026 — shipped in V1.2)*

The related payment-request flow (`fulfillPayRequest`, `sendPayment`) previously trusted the boolean return of `transferFrom` without verifying actual balance change. Malicious or non-standard tokens could return `true` without moving any tokens, emitting a phantom-success event.

**Fix:** Before/after balance check on recipient. Any token that reports a successful transfer but doesn't actually transfer is rejected via `revert`. Fee-on-transfer tokens are also rejected at this guard (received < declared).

Chat messaging itself doesn't move tokens, so it was unaffected — but the same contract handles payment requests, so the fix hardens the whole surface.

→ Next: **OTC & Payment Requests** — the payment side of the social layer.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://durianandfun.gitbook.io/durianfun/durian-social/durian-chat.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
