Files
volana/docs/volana-design-brief.md
2026-07-02 17:26:43 +02:00

27 KiB
Raw Blame History

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."

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