initial commit

This commit is contained in:
thesn10
2026-07-02 17:26:43 +02:00
commit 2d4431cb16
24 changed files with 31592 additions and 0 deletions

558
docs/volana-design-brief.md Normal file
View File

@@ -0,0 +1,558 @@
# Volana — Consumer Frontend Design Brief
> This document is the sole source of truth for the Claude Design session. It contains everything needed to design the Volana consumer marketplace frontend: brand context, product vision, UX goals, data models, page inventory, interaction patterns, and content guidance. Visual design decisions (color, typography, spacing, motion) are left to the designer.
---
## 1. What is Volana?
**Volana is a decentralized, censorship-resistant marketplace** — think eBay, but on Solana. The primary inspiration is eBay's consumer UX (browse listings, view a product, buy it), with two fundamental differences:
1. **Nobody can censor it.** No government, no company, no intermediary can remove a listing or block a transaction. The marketplace is governed entirely by open-source smart contracts on Solana. Anyone can list anything, and no third party can intervene.
2. **Payments are final and predictable.** Unlike PayPal (which can reverse a payment weeks later) or traditional card payments (chargebacks), payments on Volana go through on-chain escrow contracts. Once the buyer releases the funds, they are final. The entire payment flow is encoded in open smart contracts — anyone can read exactly what will happen before they sign anything. There are no hidden fees, no unexpected reversals, and no intermediary who can freeze your funds.
**Target audience for this design:** Regular online shoppers who are crypto-curious or already have a Solana wallet (Phantom, Solflare, Backpack, etc.). They are used to eBay or Amazon. They do not need to understand blockchain to use Volana — but they should feel like they are on something more trustworthy and modern.
**Scope of this design sprint:** Consumer-facing frontend only. This means:
- Homepage / listing browse (like eBay's search results page)
- Listing detail page (like eBay's product page)
- The "place order" / checkout flow (connect wallet → confirm purchase)
- Wallet connect / account state in the nav
- My Orders / Order status
**Out of scope for now:** seller dashboard, dispute resolution UI, resolver management, technical on-chain explorer views.
---
## 2. Why Volana Exists — The Value Propositions (Use in Copy & Tone)
These are the core benefits. The design should make them feel real, not like marketing:
### 2a. True Freedom of Commerce
No government, no corporation, no payment processor can remove a listing or block a purchase. The marketplace runs on open-source contracts on a public blockchain. Even if the Volana website went offline, someone could spin up a new frontend that reads the same on-chain data and resume trading.
### 2b. Final, Predictable Payments
- **PayPal/credit card problem:** A buyer can initiate a chargeback 6 months after a sale. Sellers live in constant fear of payment reversals.
- **Volana's solution:** Payment flows through a smart contract escrow. The buyer locks funds in the escrow when placing an order. The seller confirms the order. The buyer releases funds when they receive the goods. Once released, the transfer is final — no third party can reverse it.
- **Predictability:** The exact payment flow (including dispute resolution) is encoded in open contracts. Anyone can audit them before transacting.
### 2c. Ultra-Low Fees
Solana transactions cost fractions of a cent. Volana charges no percentage fee — the only costs are Solana network fees (< $0.001 per transaction) and, if a dispute arises, the resolver's fee (typically 0.52% of the transaction, only charged if the dispute is actually resolved). Compare this to eBay (1013%) or PayPal (34%).
### 2d. Permissionless Dispute Resolution
If something goes wrong, a neutral third-party resolver (chosen by the buyer at checkout, from a list the seller accepts) adjudicates the dispute. The resolver's ruling is enforced on-chain — neither buyer nor seller can override it. The resolver earns a small fee only when they rule on a case.
---
## 3. Brand Identity
### Name
**Volana** — the consumer-facing brand. The underlying protocol is "Solisting/Descro" but regular users never need to know that. The brand is "Volana."
### Personality
Modern, clean, trustworthy, slightly edgy (freedom angle), fast. Not "crypto bro" — approachable. Not corporate — honest. Not cheap — premium but accessible.
### Tagline options (for reference)
- *"Trade freely. Pay finally."*
- *"The marketplace nobody controls."*
- *"Buy anything. Pay once. For real."*
### Visual Mood
The design should feel like a **dark-mode-first modern marketplace** with a premium, slightly futuristic feel. Reference points: a modern SaaS product, not a financial terminal. Solana's brand identity (purple/green) can be an influence but doesn't have to dominate. The primary CTA ("Buy Now") should feel like the most important thing on screen wherever it appears.
---
## 4. Technical Context — What Data Exists On-Chain
The frontend reads two Solana programs:
### 4a. `solisting` program — Listings and Orders
**ListingAccount** (one per product listing):
- `seller: Pubkey` — the seller's wallet address (32-byte Solana public key)
- `name: String` — product name (max 64 chars)
- `description: String` — product description (max 256 chars)
- `metadata_uri: String` — URL to a JSON file with additional metadata (image, more details) (max 256 chars)
- `price: u64` — price in the canonical currency's smallest unit
- `canonical_currency` — either `Sol` (native SOL, 9 decimals) or `Spl { mint, decimals }` (an SPL token)
- `alt_currencies: Vec<AltCurrencyConfig>` — other currencies the seller accepts (max 3). Price is auto-converted via Pyth oracle at order time.
- `quantity: u32` — total units available
- `quantity_reserved: u32` — units currently held by pending orders. Available = quantity quantity_reserved.
- `is_active: bool` — whether the listing accepts new orders
- `accepted_resolvers: Vec<Pubkey>` — resolvers this seller trusts. Empty = any registered resolver accepted.
- `listing_id: u64` — unique identifier per seller
**OrderAccount** (one per purchase):
- `listing: Pubkey` — which listing this order is for
- `buyer: Pubkey` — the buyer's wallet
- `seller: Pubkey` — the seller's wallet
- `resolver: Option<Pubkey>` — the dispute resolver chosen at checkout
- `payment_currency` — the currency the buyer chose to pay in
- `amount: u64` — the actual amount paid (oracle-computed if not canonical currency)
- `escrow_account: Pubkey` — the linked escrow on the `descro` program
- `created_at: i64` — Unix timestamp
### 4b. `descro` program — Escrow State Machine
Each order has a corresponding **EscrowAccount** with a state machine:
```
AwaitingSellerConfirm → Active → Complete
↘ ↘ Cancelled
↘ Disputed → Resolved (Complete or Cancelled)
```
- **AwaitingSellerConfirm:** Buyer has locked funds. Waiting for the seller to confirm the order. Buyer can cancel for a full refund in this phase.
- **Active:** Seller confirmed. Funds locked. Buyer should receive the goods. Buyer can confirm receipt (→ Complete) or raise a dispute.
- **Complete:** Buyer confirmed receipt. Seller receives funds. Final.
- **Cancelled:** Either the buyer cancelled before the seller confirmed, the seller rejected, or a dispute was resolved in the buyer's favor. Buyer gets refunded.
- **Disputed:** A dispute was raised. A resolver will adjudicate.
**For the consumer frontend, the relevant states are:**
- When browsing: show available quantity (quantity quantity_reserved)
- At checkout: the buyer places an order which goes immediately to `AwaitingSellerConfirm`
- In "My Orders": show order state + available actions
### 4c. Resolvers (dispute arbitrators)
**ResolverEntry** — registered dispute resolvers:
- `name: String` — resolver's display name
- `description: String` — what they handle / their policy
- `fee_bps: u16` — fee in basis points (100 bps = 1%). Charged only if they rule on a dispute.
- `resolver_type` — e.g., Automated / Human / DAO
- `acceptance_policy` — AutoAccept (takes all cases) or ManualAccept (can decline)
- `ruled_for_buyer: u32` — historical rulings for the buyer
- `ruled_for_seller: u32` — historical rulings for the seller
At checkout, the buyer selects a resolver from the list the seller accepts.
### 4d. Currency / Price Display Rules
- **SOL:** price in lamports (divide by 1,000,000,000 to get SOL). Display as "X SOL".
- **SPL tokens:** price in smallest unit (divide by 10^decimals). Display with token symbol.
- **Stablecoins** (USDC, USDT, etc.): oracle = None, $1.00 peg assumed.
- **Alt currency prices** are computed at order time by the on-chain oracle. The buyer passes an `expected_amount` and `max_slippage_bps` to protect against price movement.
---
## 5. Page Inventory & UX Specification
### Priority: Consumer Frontend Only
The design session should focus exclusively on the **buyer experience**:
1. **Homepage / Browse Listings** (highest priority)
2. **Listing Detail / Product Page** (highest priority)
3. **Checkout / Place Order flow** (highest priority)
4. **Wallet Connect** (integrated into nav)
5. **My Orders / Order Status** (lower priority, can be a simple list)
The following are **out of scope** for this design sprint:
- Seller dashboard (create/manage listings)
- Dispute resolution UI
- Resolver management
- Technical on-chain explorer views
- Admin/protocol views
---
### Page 1: Homepage / Browse Listings
**URL:** `/` or `/browse`
**Purpose:** The product catalog. Like eBay's search results or Amazon's browse page. The primary conversion surface.
**UX Goals:**
- Buyer should immediately see products and understand what Volana is
- Scanning products should feel fast — like a physical store, not a terminal
- Price, image, availability should be instantly readable
- Category/search/filter should be accessible without needing to know how blockchain works
**Layout concept:**
- Hero / value prop section at the top (first visit only, or collapsible): headline + 2-3 key benefit chips (e.g. "Final payments", "No censorship", "< $0.001 fees")
- Below hero: search + filter bar
- Product grid (primary): card-based layout like eBay. Each card has:
- Product image (from metadata_uri → JSON → image field; fallback: placeholder)
- Product name (from `listing.name`)
- Price prominently displayed (formatted: "1.5 SOL" or "12.00 USDC")
- Availability indicator: "In Stock" / "Low Stock" (when ≤ 3 available) / "Out of Stock"
- Seller abbreviation (first 4 + last 4 chars of wallet address)
- "Buy" button (opens checkout flow)
**Filters / Search:**
- Search bar: searches listing names and descriptions
- Filter by currency: All / SOL / USDC / Other
- Filter by price range
- Filter by availability: In Stock only (default on)
- Sort: Newest / Price: Low to High / Price: High to Low
**Card states:**
- Active + in stock: fully interactive
- Active + out of stock: visible but "Out of Stock" label, buy button disabled
- Inactive: hidden from browse view by default
**Technical data per card:**
- `listing.name` (display title)
- `listing.description` (shown on hover / card subtitle)
- `listing.price` + `listing.canonical_currency` (formatted price)
- `listing.quantity - listing.quantity_reserved` (available count)
- `listing.metadata_uri` (fetch the JSON at this URL to get the product image)
- `listing.seller` (abbreviated wallet address)
- `listing.is_active` (show/hide logic)
---
### Page 2: Listing Detail / Product Page
**URL:** `/listing/[address]`
**Purpose:** The product detail page. Like eBay's item page. Where the buyer decides to purchase.
**UX Goals:**
- The buyer should feel informed and confident
- Price and "Buy Now" should be obvious within 2 seconds of loading
- Trust signals should be visible (on-chain verification, resolver info)
- Blockchain complexity should be completely hidden — it just feels like a trustworthy product page
**Layout concept (desktop: 2-column):**
**Left column (~60%):**
- Large product image (from metadata JSON, or placeholder)
- Image gallery thumbnails if multiple images exist in metadata
- Product name (primary heading)
- Description (full text, with "show more" if long)
- Seller info row: abbreviated address + copy button + "Verified on Solana" label
- Technical details expandable section (for advanced users): listing ID, on-chain address
**Right column (~40%, sticky while scrolling):**
- Price (large, prominent) — show canonical price + note if other currencies accepted
- Availability: "X in stock" with a visual indicator when low
- Currency selector: if the listing accepts multiple currencies, let the buyer pick which to pay with
- Resolver selector: shows accepted resolvers with their fee %. Pre-select a recommended one. Fee is labeled as "only charged if dispute is resolved."
- **"Buy Now" button** — the primary CTA, most prominent element on the page
- Below CTA: 3 trust signals:
- "Final Payment" — payment cannot be reversed
- "Dispute Protection" — a resolver mediates if something goes wrong
- "On-chain Verified" — all terms are in open smart contracts
- Note: "Funds held in escrow until you confirm receipt"
**Seller section** (below the grid):
- Abbreviated seller address + copy
- Number of active listings by this seller (optional, if easily fetchable)
---
### Page 3: Checkout / Place Order
**Design as a modal or side panel** — keep the user on the product page, don't navigate away.
**Trigger:** Clicking "Buy Now" on the listing detail page.
**Pre-condition — wallet not connected:**
- "Buy Now" opens a wallet connect modal first
- After connecting, resume the checkout flow automatically
**Step 1: Order Review**
The user sees a summary before committing:
```
Buying: [Product Name]
Seller: [abbreviated address]
Payment
Currency: [SOL ▾] ← dropdown if multiple currencies accepted
Amount: 1.5 SOL ≈ $180 USD ← show USD estimate alongside
[] This amount may vary slightly due to real-time price conversion.
Slippage tolerance: 0.5% ← shown, but pre-set to sensible default
Dispute Protection
[Resolver Name — 0.5% fee if dispute resolved] [▾ Change]
← First/recommended resolver pre-selected
"Resolver fee is only charged if a dispute is actually adjudicated."
[Cancel] [Confirm & Place Order →]
```
**Step 2: Transaction pending**
- The wallet extension popup appears (handled by browser)
- The modal shows a loading/pending state: "Confirming on Solana…"
**Step 3: Confirmation (after transaction confirmed)**
```
✓ Order placed successfully!
Your payment of 1.5 SOL is now held in secure escrow.
The seller has been notified and will confirm your order.
What happens next:
1. Seller confirms → your order becomes active
2. You receive the goods
3. You confirm receipt → seller gets paid
4. If something goes wrong, [Resolver Name] will mediate
[View My Orders] [Continue Shopping]
```
**Error states:**
- Wallet rejected: "Purchase cancelled."
- Out of stock (race condition): "Sorry, this item just sold out."
- Slippage exceeded: "The price changed too much before your transaction went through. Please try again."
- Network error: "Connection issue. Please try again."
**What happens under the hood (invisible to the user):**
- Frontend calls `solisting::create_order` on-chain
- This atomically: validates the listing, computes the oracle-adjusted price if paying in an alt currency, increments `quantity_reserved`, and creates a `descro` escrow (moves funds from buyer's wallet into the escrow vault)
- After the transaction confirms, an `OrderAccount` exists on-chain linking the listing to the escrow
---
### Page 4: Wallet Connect (in Nav)
**Disconnected state:**
- Prominent "Connect Wallet" button on the right of the nav
**On click:** Opens wallet selection modal listing installed wallets (Phantom, Solflare, Backpack, etc.) via `@solana/connector`.
**Connected state:**
- Shows an abbreviated wallet address (first 4 + last 4 chars) with a connected indicator dot and a dropdown arrow
**On click — dropdown:**
- Wallet name + icon
- Full address (copyable)
- [Copy Address] button
- [Disconnect] button
---
### Page 5: My Orders (Order Status)
**URL:** `/orders` — visible in nav only when wallet is connected
**Content:** A list of the connected wallet's OrderAccounts:
- Product name (linked to listing detail)
- Amount paid
- Current status (Awaiting Confirm / Active / Complete / Cancelled / Disputed)
- Date placed
- Link to full order detail
**Order Detail page** (`/order/[address]`):
- Order ID and date
- Linked listing (clickable)
- Amount in escrow
- Current escrow state visualized as a linear progress:
```
[1. Awaiting Confirm] → [2. Active] → [3. Done]
```
Current step highlighted; terminal outcome (Complete / Cancelled) shown separately
- Status-appropriate actions:
- `AwaitingSellerConfirm` state → [Cancel Order] (full refund)
- `Active` state → [Confirm Receipt] (releases payment to seller)
- Terminal states → informational only, no actions
---
## 6. Navigation Structure
```
[Volana Logo] [Search bar] [Browse] [My Orders] [Network ▾] [Connect Wallet]
```
- **Logo** → homepage/browse
- **Browse** → `/browse`
- **My Orders** → `/orders` (only shown when wallet connected)
- **Network picker** → dropdown to switch between Mainnet-beta, Devnet, Localnet (indicated by a colored dot per network)
- **Wallet button** → connect/disconnect
**Mobile nav:** collapsed behind a hamburger; wallet connect accessible from the top of the menu.
---
## 7. UI Component Inventory
These are the components that need to exist. Visual design is up to the designer.
### Product Card (Browse Grid)
Required information hierarchy:
1. Product image (top, full width of card)
2. Product name (bold, prominent)
3. Seller abbreviation (small, secondary)
4. Price (prominent, clear)
5. Availability label (In Stock / Low Stock / Out of Stock)
6. Buy button (at bottom or on hover)
### Status Labels
The following statuses need distinct visual treatment (not just color — also shape/icon/text so they're accessible):
- **In Stock** — positive/active
- **Low Stock** — urgency/warning (≤ 3 available)
- **Out of Stock** — disabled/unavailable
- **Awaiting Confirm** — pending/waiting
- **Active** (order) — in progress
- **Complete** — success/terminal
- **Cancelled** — neutral/terminal
- **Disputed** — alert/problem
### Trust Badge Strip
Three small badges used on the listing detail page and in the checkout flow:
- "Final Payment"
- "Dispute Protection"
- "On-chain Verified"
### Checkout Modal / Sheet
- Overlay/modal on desktop
- Full-screen bottom sheet on mobile
- Contains: order summary, currency picker, resolver picker, CTA button, pending/success states
### Toast / Notification
- Transient notification for feedback: "Address copied", "Order placed!", errors
- Should appear without interrupting the user flow
### Loading / Skeleton States
- Product grid: skeleton cards while listings load from the blockchain (can take 13 seconds)
- Listing detail: skeleton for image and fields
- Button: loading spinner while transaction is pending on-chain
---
## 8. Key UX Principles
### 8a. Hide the Blockchain
- Never show raw 44-character public keys as primary information — abbreviate (first 4 + "…" + last 4 chars), and offer a copy button or "view on explorer" link
- Price is shown in human-readable format: "1.5 SOL", not "1500000000 lamports"
- Escrow states should be explained in plain English (see copy guidance), not contract terminology
- The transaction flow should feel like clicking a "Confirm" button — the wallet popup is the only visible blockchain interaction
### 8b. Trust Through Transparency (for those who want it)
- Provide optional "see on-chain" links for technically-minded users — don't hide it, just don't foreground it
- The "How it works" section (in footer or dedicated page) explains the escrow flow in plain language with a simple step diagram
- Resolver selection should feel like choosing a "dispute protection plan" — not a cryptographic concept
### 8c. Conversion Optimization
- The primary "Buy Now" CTA must be above the fold on the listing detail page (sticky in the right column as user scrolls)
- Urgency messaging: "Only 2 left!" when available ≤ 3
- No account creation — connecting a wallet is the account
- Checkout is 1 step (review + confirm) — not a multi-page funnel
- Post-purchase: immediately show order status with clear "what happens next" steps — reduce post-purchase anxiety
### 8d. Responsive / Mobile
- Browse grid: 1 column on small mobile, 2 on large mobile/tablet, 34 on desktop
- Listing detail: single column on mobile (image → price/buy panel → description)
- Checkout: full-screen bottom sheet on mobile (not a floating modal)
### 8e. Performance Perception
- Product images load lazily with a placeholder shown immediately (blur-up or skeleton)
- Show previously cached listing data while re-fetching — never show a blank screen if stale data exists
- The page should feel fast even when waiting on blockchain RPC responses
---
## 9. Content & Copy Guidance
### Terminology to Use vs. Avoid
| ❌ Avoid (crypto jargon) | ✅ Use instead |
|-----------------------------------|---------------------------------------|
| "Sign a transaction" | "Confirm your purchase" |
| "Escrow account" | "Secure payment hold" |
| "PDA / program derived address" | (hide entirely from user) |
| "Lamports" | "SOL" (always convert and display) |
| "CPI" / "on-chain instruction" | (hide entirely from user) |
| "Resolver" (without context) | "Dispute mediator" or "Protection" |
| "Canonical currency" | "Primary currency" |
| "Pubkey" | "Wallet address" |
| "Quantity reserved" | "Pending orders" |
| "is_active: false" | "Listing closed" / "Not available" |
### Error Messages (User-Facing)
- Wallet declined: "Purchase cancelled."
- Network error: "Connection issue. Please try again."
- Out of stock (race): "Someone else just bought the last one. Sorry!"
- Slippage exceeded: "The price changed too much before your transaction went through. Please try again."
- Wallet not connected: "Connect your wallet to buy."
### How It Works (for footer / explainer page)
Plain-language 4-step flow for curious users:
1. **Browse & pick** — find something you want to buy
2. **Place order** — connect your wallet and confirm. Your payment is locked in a secure escrow (a smart contract nobody can tamper with).
3. **Receive & confirm** — when you receive your goods, confirm receipt. The payment is released to the seller automatically.
4. **Protected** — if something goes wrong, your chosen dispute mediator steps in. Their ruling is final and enforced on-chain.
---
## 10. Technical Stack Reference
For context on what data is available and how the frontend fetches it:
- **Frontend:** Next.js 16, React 19, App Router
- **Wallet:** `@solana/connector` — standard Solana wallet adapter; provides `useWallet()`, `useCluster()`, transaction signing
- **Data fetching:** React Query — polls Solana RPC for on-chain account data
- **SDK:** `@solisting/sdk` — typed fetchers for `ListingAccount`, `OrderAccount`, etc.
- **Networks:** Mainnet-beta, Devnet, Localnet (switchable in the nav)
- **Payments currently supported:** SOL (native). SPL tokens (USDC etc.) are planned — the contract infrastructure supports them but the frontend doesn't wire them up yet.
- **Product images:** stored off-chain. The seller provides a `metadata_uri` (URL to a JSON file) which contains the image URL. The JSON format follows the standard Solana NFT metadata schema: `{ name, description, image, ... }`.
---
## 11. Flows to Design (Priority Order)
1. **Browse → Product Detail → Buy Now (connected wallet)** — the primary happy path
2. **Browse → Product Detail → Buy Now (wallet not connected)** → connect wallet → complete checkout
3. **Post-purchase confirmation** — order summary + "what happens next"
4. **My Orders list** — status overview of buyer's orders
5. **Order Detail** — current state + available actions (confirm receipt / cancel)
---
## 12. What Makes Volana Different from Traditional Marketplaces
Use in hero copy, onboarding tooltips, and "How it works":
| Feature | eBay / Amazon / PayPal | Volana |
|-------------------------|------------------------------------------|------------------------------------------------|
| Censorship resistance | Any listing can be removed | No one can remove a listing |
| Payment reversal | Chargebacks possible for months | Payments are final once the buyer confirms |
| Fees | 1013% platform + 34% payment processor | < $0.001 network fee only |
| Dispute resolution | Black-box, provider-controlled | On-chain, auditable, mediator of your choice |
| Account required | Email + card + KYC | Solana wallet only |
| Transparency | Terms can change at any time | Rules are open-source smart contracts |
---
## 13. Accessibility Requirements
- All interactive elements must have visible focus states
- Status labels must never rely on color alone — pair color with a text label or icon
- Product cards must be fully keyboard-navigable
- Wallet connection modal must be screenreader-compatible (ARIA roles, focus trap)
- Minimum contrast ratio for body text: 4.5:1 (WCAG AA)
---
## 14. Screen States to Cover
### Browse Page
- **Loading:** placeholder/skeleton cards while blockchain data is fetched
- **Loaded:** product grid with filters active
- **Empty:** no listings on the selected network — suggest switching to Mainnet
- **No results:** search/filter combination returns nothing
### Listing Detail
- **Loading:** skeleton for image, title, price panel
- **Loaded:** full detail with all fields
- **Out of Stock:** detail still visible, "Buy Now" replaced with "Out of Stock" (disabled)
- **Wallet not connected:** "Buy Now" says "Connect Wallet to Buy" — click opens wallet modal
### Checkout Modal
- **Review state:** order summary, currency/resolver selectors, confirm button
- **Pending state:** wallet popup has appeared, modal shows loading state
- **Success state:** confirmation with "what happens next"
- **Error state:** failed transaction with clear message and retry option
### My Orders
- **Empty:** no orders yet — prompt to browse
- **List with orders:** orders grouped by status or sorted by date
- **Order detail — awaiting confirm:** Cancel button available
- **Order detail — active:** Confirm Receipt button available
- **Order detail — terminal:** read-only, shows outcome