# DURIAN WALLET

## 👛 Durian Wallet

> **Your ecosystem portfolio in one place — with real P\&L for every token you touch.**

The Durian Wallet is a **non-custodial, branded sub-wallet** integrated into the Durianfun app. It replaces the default "Connect Wallet" modal with a richer experience: logos, live prices, cost-basis P\&L, and one-tap Send / Receive / Buy — all reusing your existing MetaMask or OKX signer under the hood.

> 🚧 **Status:** In active build. The specification, discovery, and Profit Thinker algorithm are finalized; UI implementation is scheduled. See the authoritative `PLAN.md` in `Durian Wallet/`.

### What It Does

```
┌──────────────────────────────────────────────────────────┐
│  Durian Wallet                                           │
│  ─────────────────────────────────────────────────────   │
│  Total Portfolio:   $ 12,483.55    +$ 1,204.30 (+10.7%)  │
│                                                          │
│  🟢 KUB   (native + KKUB merged)                         │
│      840.00 KUB   = $ 8,400.00     +18.2% (24h)          │
│                                                          │
│  ⚪ kUSDT   → $ 2,500.00            —                     │
│  ⚪ kUSDC   → $ 500.00              —                     │
│                                                          │
│  🍈 MEMEKING   3,200,000 tokens                          │
│      = $ 960.00    +47.8% (24h)                          │
│      cost basis: $ 421.00  · P&L: +$ 539.00 (+128%)      │
│                                                          │
│  [ Send ]  [ Receive ]  [ Buy ]                          │
└──────────────────────────────────────────────────────────┘
```

### Two Components

#### 1. Durian Wallet (UI Layer)

A drawer-based wallet UI inside the Durianfun app. **Does not manage keys** — it uses the parent app's signer via `useWallet()`. Every "Connect Wallet" click routes through Durian Wallet instead of the raw MetaMask / OKX modal.

**Supported actions:**

* **View portfolio** — all ecosystem tokens with logos, prices, balances.
* **Send** — `to` + `amount` + `asset` → `erc20.transfer` or native `sendTransaction`.
* **Withdraw** — same as Send, wallet-address-only UX for clarity.
* **Receive** — QR code (with Durian-branded center) + copy-address.
* **Buy** — reuses existing **BANXA on-ramp** via `BuyKubModal`.

**Brand:**

* Tailwind tokens · `text-tertiary` (green) / `text-error` (red) · `font-headline`
* `rounded-2xl` drawers · `max-w-[420px]` · 300 ms slide animation
* Logo fallback: on-chain `imageUrl` → letter chip with address-derived color
* `FlipNumber` cascade reveal on open

#### 2. Profit Thinker (P\&L Engine)

A **reusable cost-basis engine** that powers every P\&L figure in the wallet — and is available for any other Durianfun surface that wants to show unrealized gains.

**Public API:**

```typescript
getTokenPnL(userAddress, tokenAddress) => Promise<{
  balance: bigint,
  costBasisUsd: number | null,
  currentPriceUsd: number | null,
  currentValueUsd: number | null,
  unrealizedPnLUsd: number | null,
  unrealizedPnLPct: number | null,
  priceChange: { '6h': number | null, '12h': number | null, '24h': number | null }
}>
```

**React hook:**

```typescript
const { loading, pnl, refetch } = useProfitThinker(tokenAddress);
```

### How Profit Thinker Computes Cost Basis

Profit Thinker indexes **every event where the user traded this token** across four venues:

| Venue                                      | Event                        | User Filter              |
| ------------------------------------------ | ---------------------------- | ------------------------ |
| **Durianfun Factory V4.5** (bonding curve) | `TokensBought`, `TokensSold` | `buyer / seller == user` |
| **Durian CLOB**                            | `Trade`                      | `maker / taker == user`  |
| **Udonswap AMM V2**                        | `Swap`                       | `to / from == user`      |
| **Plain ERC-20 Transfers**                 | `Transfer`                   | `to / from == user`      |

Events are sorted chronologically, then a **weighted-average cost-basis** algorithm processes them in order:

```
BUY:
  newCostBasis = (oldCost + tradeCost)
  newQuantity  = (oldQty  + tradeQty)
  avgCost      = newCostBasis / newQuantity

SELL:
  realize P&L at trade price
  decrement quantity & costBasis proportionally

TRANSFER OUT:
  outflow at last avg-cost (treated as a sell at market)

TRANSFER IN from unknown address:
  ignored in v1 (airdrops skipped until v2)

unrealizedPnL = (currentPrice − avgCost) × holdingQuantity
```

### Pricing Strategy

| Asset class                | Source                                                                    |
| -------------------------- | ------------------------------------------------------------------------- |
| **Stables** (kUSDC, kUSDT) | Hardcoded $1.00                                                           |
| **Native KUB**             | Live **Udonswap KUB/kUSDT pool** (reserve ratio)                          |
| **Ecosystem tokens**       | CLOB bestBid → AMM reserve ratio → bonding-curve formula (fallback order) |

**Price-change windows (6h / 12h / 24h):** compares the oldest trade in that window's lookback period against current price. Returns `null` if the window has no trades.

### Caching & Performance

Profit Thinker caches incrementally to localStorage:

```
localStorage[pnl:${user}:${token}] = {
  lastScannedBlock: number,
  trades: UserTrade[],
  lastComputed: { balance, costBasis, ... }
}
```

* **First load:** scan last **90 days** of events.
* **Subsequent loads:** scan from `lastScannedBlock` onward.
* **Cache invalidation:** on new trade detected, on 90-day rolling purge.

### Scope — What's In v1 / Deferred to v2

#### In v1

* All four data sources (curve, CLOB, AMM, ERC-20 transfers)
* Average-cost P\&L with realized/unrealized split
* 6h/12h/24h price-change windows
* Send / Receive / Buy / Withdraw UI
* Replaces wallet connect modal ecosystem-wide

#### Deferred to v2

* Spot Vault balance display (show CLOB locked + free)
* Historical base-USD price indexing (better accuracy for old trades)
* Airdrop cost-basis handling (currently skipped)
* In-wallet swap (Udonswap router)
* HOP multi-hop pathfinding
* Cross-chain Send / Withdraw
* Watchlist tab for unowned tokens
* ENS / KubID resolution

### Integration with Parent App

The main Durianfun app uses a **custom `WalletContext`** — not wagmi/RainbowKit. The Durian Wallet reads from `useWallet()`:

```typescript
const { signer, address, chainId, isConnected, connect, disconnect } = useWallet();

// Trigger connection type-specific:
await connect("metamask");  // or "okx"
```

No re-prompts. No duplicate connection flows. Seamless.

### Ecosystem Addresses (Confirmed, Mainnet)

| Item                       | Address                                                    |
| -------------------------- | ---------------------------------------------------------- |
| CLOB Factory               | `0x1e963da022030D29D952e7e0c944F6bfAC50b0e7`               |
| Factory V4.5               | `0xdf4f3dB298A9aDe853191F58b4b2a322D47EC005`               |
| Factory-D V2.5             | `0xa1000BB39f36a630F1AB1b245B25Ca75a6744Aa5`               |
| Udonswap AMM Factory       | `0x18c7dd09c6fa45b2cab5a0bb48b20f5db08fe8d1`               |
| KUB Price Pool (KUB/kUSDT) | `0xA790e265…`                                              |
| kUSDT                      | `0x7d984C24d2499D840eB3b7016077164e15E5faA6` (18 decimals) |
| kUSDC                      | `0x77071ad51ca93fc90e77BCdECE5aa6F1B40fcb21` (18 decimals) |

> ⚠️ KUB mainnet stables are **18-decimal** — not 6 like on Ethereum. Always use `token.decimals()`.

### Audits

Durian Wallet contracts are **social-layer contracts** (`DurianSocial_V1_2`, `DurianMoneyTransfer_V1_2`) with four audit findings fixed in V1.2:

* **\[M3]** Chat / Payment balance-delta guard
* **\[C1] / \[H1]** OTC escrow FoT-token rejection + balance-delta guard
* **\[M1]** OTC native-reject pull-pattern fallback
* **\[M2]** OTC fee snapshot at creation

See **OTC & Payment Requests → Security** for full patch details, or the **Full Audit Report** for the cross-ecosystem view.

The wallet UI itself has **no custody surface** — it's a pure read + UX layer on top of user's existing wallet signer. No additional audit scope.


---

# 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-wallet.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.
