feat: add Neroswap product page, blog post, and portfolio entry

- Product page at /products/neroswap with exchange descriptions, features, and architecture
- Blog post at /blog/neroswap-aggregator explaining the data pipeline and privacy design
- Added to products listing (first position, yellow color)
- Added to bento grid portfolio section
- Links to neroswap.com throughout
- SEO metadata with keywords, canonical URLs, Open Graph
This commit is contained in:
jwinterm
2026-03-17 12:49:34 -04:00
parent d6f8cc6213
commit 931f80abdf
4 changed files with 300 additions and 2 deletions
@@ -0,0 +1,59 @@
---
title: "Neroswap: a Privacy-First DEX & CEX Aggregator"
date: "2025-06-28"
excerpt: "How we built a real-time orderbook aggregator across 6 decentralized and centralized exchanges — with no KYC, no custody, and no tracking."
---
## The Problem
If you want to trade Monero or Wownero today, your options are scattered across half a dozen exchanges — each with a different UI, different pair formats, and wildly different prices. Some are decentralized atomic swaps; others are no-KYC centralized platforms. Comparing prices means opening six browser tabs and doing mental math.
[Neroswap](https://neroswap.com) fixes that.
## What Neroswap Does
Neroswap is a real-time aggregator that pulls orderbook and ticker data from six exchanges and displays it in a single, unified dashboard. You can see best prices at a glance, filter by exchange type (DEX vs CEX) or coin (XMR vs WOW), and click directly through to the source exchange to trade.
The exchanges currently tracked are:
- **BasicSwap** — SMSG-based atomic swaps for BTC, LTC, XMR, PART, WOW, FIRO, DASH, and more
- **Retoswap** — P2P exchange for XMR fiat/crypto pairs, trades settle over Tor
- **Eigenwallet** — BTC ↔ XMR trustless atomic swaps via Tor rendezvous
- **Nonlogs** — No-KYC Wownero-focused exchange with WOW/BTC and WOW/USDT
- **CexSwap** — Spot markets and AMM liquidity pools across 40+ coins
- **AltQuick** — No-KYC altcoin exchange with 25+ BTC-quoted markets
Kraken reference prices are used to compute approximate USD values for every pair.
## How the Data Pipeline Works
Neroswap runs a fleet of Python scrapers on a dedicated server. Each scraper targets one exchange and runs every 10 minutes via cron:
1. **Scraping** — Each script queries its exchange via REST API, gRPC, HTML-over-Tor, or direct RPC. BasicSwap and Retoswap are scraped via local full nodes; Eigenwallet via its Tor onion; Nonlogs, CexSwap, and AltQuick via public APIs.
2. **Normalization** — Raw data is transformed into a common JSON schema with fields like `pair`, `price`, `amount`, `type` (bid/ask), and `source`.
3. **Sync** — The JSON files are rsync'd to a CDN edge server over SSH every 10 minutes, right after the scrapers finish.
4. **Serving** — The [neroswap.com](https://neroswap.com) frontend is a Next.js app using ISR (Incremental Static Regeneration). It fetches the JSON data from the CDN on each request with a 5-minute revalidation window, so the data is always fresh.
5. **Rendering** — The frontend computes best bid/ask prices across all sources, applies Kraken USD reference rates, and renders sortable, filterable tables. Every row links back to the source exchange.
## Privacy by Design
Neroswap has no user accounts, no cookies, no tracking pixels, and no analytics. There is nothing to log and nothing to sell. The entire site is a read-only dashboard — it never touches your funds or your identity.
All the DEX sources (BasicSwap, Eigenwallet) are fully decentralized with on-chain or cross-chain atomic settlement. The CEX sources (Nonlogs, CexSwap, AltQuick) are all no-KYC platforms. Retoswap trades happen entirely over Tor.
## The Stack
- **Frontend**: Next.js (App Router), React, TypeScript, Tailwind CSS
- **Scrapers**: Python scripts with requests, grpc, and stem (Tor)
- **Data transport**: rsync over SSH to CDN, served as static JSON
- **Infrastructure**: Systemd services, cron scheduling, PM2 process management
## Try It
Visit [neroswap.com](https://neroswap.com) to see the live dashboard.
The project is built and maintained by [Such Software](/#contact). If you need a custom aggregator, scraping pipeline, or privacy-first web application, [get in touch](/#contact).
+221
View File
@@ -0,0 +1,221 @@
import { Header } from "@/components/layout/header";
import { MobileNav } from "@/components/layout/mobile-nav";
import { Card } from "@repo/ui/components/card";
import { Button } from "@repo/ui/components/button";
import Link from "next/link";
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Neroswap — Aggregated DEX & CEX Orderbook Data | Such Software",
description:
"Real-time aggregated orderbook data across decentralized and centralized exchanges. Compare Monero, Wownero, and Bitcoin prices across BasicSwap, Retoswap, Eigenwallet, Nonlogs, CexSwap, and AltQuick — no KYC, no custody.",
alternates: { canonical: "/products/neroswap" },
openGraph: {
title: "Neroswap — DEX & CEX Aggregator",
description:
"Compare crypto prices across 6 exchanges in real time. Privacy-focused, self-sovereign, no KYC.",
type: "website",
url: "https://such.software/products/neroswap",
},
keywords: [
"neroswap",
"dex aggregator",
"cex aggregator",
"monero exchange",
"wownero exchange",
"basicswap",
"atomic swap",
"no kyc exchange",
"crypto price comparison",
"decentralized exchange aggregator",
"privacy coin exchange",
],
};
const exchanges = [
{
name: "BasicSwap",
type: "DEX",
desc: "SMSG atomic swaps — BTC, LTC, XMR, PART, WOW, FIRO, DASH & more. Fully decentralized, on-chain settlement.",
},
{
name: "Retoswap",
type: "DEX",
desc: "P2P exchange for XMR ↔ fiat and crypto pairs. Trades settle over Tor for maximum privacy.",
},
{
name: "Eigenwallet",
type: "DEX",
desc: "BTC ↔ XMR trustless atomic swaps via Tor rendezvous. No intermediary at any point.",
},
{
name: "Nonlogs",
type: "CEX",
desc: "No-KYC Wownero-focused exchange with WOW/BTC, WOW/USDT, and other pairs.",
},
{
name: "CexSwap",
type: "CEX",
desc: "Wownero CEX with spot markets and AMM liquidity pools across 40+ coins.",
},
{
name: "AltQuick",
type: "CEX",
desc: "No-KYC altcoin exchange with 25+ BTC-quoted markets including WOW and XMR.",
},
];
const features = [
{
title: "No KYC, No Custody",
desc: "Neroswap is a read-only aggregator. It never holds funds, never asks for identity, and has no accounts. You trade directly on the source exchange.",
},
{
title: "Real-Time Data Pipeline",
desc: "Scrapers run every 10 minutes on our infrastructure, pulling live orderbooks and ticker data from all 6 exchanges. Data is served via CDN.",
},
{
title: "Best Price Discovery",
desc: "The dashboard compares prices across all sources and highlights the best bid/ask for each pair. Filter by DEX, CEX, WOW, or XMR.",
},
{
title: "Clickable Markets",
desc: "Every ticker row links directly to the market on the source exchange. Find the best price, click, and trade — no extra steps.",
},
{
title: "Kraken Reference Prices",
desc: "BTC and XMR USD reference prices from Kraken are used to compute approximate USD values across all pairs.",
},
{
title: "Open Architecture",
desc: "Next.js frontend with ISR caching. Python scrapers on a dedicated server. JSON data served over HTTPS. Easy to extend with new exchanges.",
},
];
export default function NeroswapPage() {
return (
<main className="relative min-h-screen flex flex-col items-center bg-background text-foreground">
<Header />
<div
id="main-content"
className="z-10 w-full max-w-4xl mx-auto py-20 px-4 pb-24 md:pb-20"
>
<Link
href="/products"
className="text-sm text-muted-foreground hover:text-foreground mb-8 inline-block"
>
← Back to Products
</Link>
<h1 className="text-4xl md:text-5xl font-bold mb-6 text-yellow-600 dark:text-yellow-400">
Neroswap
</h1>
<div className="prose dark:prose-invert max-w-none mb-12">
<p className="text-xl text-muted-foreground leading-relaxed">
Aggregated DEX &amp; CEX orderbook data across decentralized and
centralized exchanges. Compare Monero, Wownero, and Bitcoin prices
in real time. No KYC. No custody. Self-sovereign.
</p>
</div>
<div className="flex flex-wrap gap-4 mb-12">
<a
href="https://neroswap.com"
target="_blank"
rel="noopener noreferrer"
>
<Button size="lg">Visit neroswap.com</Button>
</a>
</div>
<h2 className="text-2xl font-bold mb-6">Supported Exchanges</h2>
<div className="grid md:grid-cols-2 gap-6 mb-12">
{exchanges.map((ex) => (
<Card
key={ex.name}
className="glass-card border-yellow-500/20"
>
<div className="flex items-center gap-2 mb-3">
<h3 className="text-xl font-bold">{ex.name}</h3>
<span
className={`rounded px-2 py-0.5 text-xs font-medium ${
ex.type === "DEX"
? "bg-emerald-500/20 text-emerald-600 dark:text-emerald-400"
: "bg-blue-500/20 text-blue-600 dark:text-blue-400"
}`}
>
{ex.type}
</span>
</div>
<p className="text-muted-foreground">{ex.desc}</p>
</Card>
))}
</div>
<h2 className="text-2xl font-bold mb-6">Features</h2>
<div className="grid md:grid-cols-2 gap-6 mb-12">
{features.map((f) => (
<Card
key={f.title}
className="glass-card border-yellow-500/20"
>
<h3 className="text-xl font-bold mb-3">{f.title}</h3>
<p className="text-muted-foreground">{f.desc}</p>
</Card>
))}
</div>
<div className="section-container border-l-4 border-yellow-500 mb-12">
<h2 className="text-2xl font-bold mb-4">How It Works</h2>
<p className="text-muted-foreground leading-relaxed mb-4">
Neroswap runs a fleet of Python scrapers on a dedicated server. Every
10 minutes, each scraper pulls the latest orderbook or ticker data
from its exchange — via API, gRPC, or HTML scraping over Tor. The
results are merged into JSON files and synced to a CDN edge server.
</p>
<p className="text-muted-foreground leading-relaxed">
The{" "}
<a
href="https://neroswap.com"
className="text-yellow-600 dark:text-yellow-400 underline"
target="_blank"
rel="noopener noreferrer"
>
neroswap.com
</a>{" "}
frontend is a Next.js app with ISR caching. It fetches the cached
JSON on demand, computes best prices and USD estimates, and renders
sortable, filterable tables for each exchange. Every row links back
to the source exchange so you can trade immediately.
</p>
</div>
<div className="section-container border-l-4 border-yellow-500 mb-12">
<h2 className="text-2xl font-bold mb-4">Privacy First</h2>
<p className="text-muted-foreground leading-relaxed">
Neroswap has no user accounts, no tracking, no cookies, and no
analytics. The site is a static read-only dashboard. All exchanges
listed are either fully decentralized (BasicSwap, Eigenwallet) or
no-KYC (Nonlogs, CexSwap, AltQuick). Retoswap trades are conducted
entirely over Tor.
</p>
</div>
<div className="flex gap-4">
<a
href="https://neroswap.com"
target="_blank"
rel="noopener noreferrer"
>
<Button>Launch Neroswap</Button>
</a>
<Link href="/blog/neroswap-aggregator">
<Button variant="outline">Read the Blog Post</Button>
</Link>
</div>
</div>
<MobileNav />
</main>
);
}
+9 -1
View File
@@ -6,7 +6,7 @@ import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Products | Such Software",
description: "Tools and applications built by Such Software. Webshops, custom websites, Smirk Wallet, Bauhaus Echo, and Wownero Moon Launch.",
description: "Tools and applications built by Such Software. Neroswap, Webshops, custom websites, Smirk Wallet, Bauhaus Echo, and Wownero Moon Launch.",
alternates: { canonical: "/products" },
openGraph: {
title: "Products | Such Software",
@@ -16,6 +16,12 @@ export const metadata: Metadata = {
};
const products = [
{
slug: "neroswap",
title: "Neroswap",
description: "Aggregated DEX & CEX orderbook data. Compare Monero, Wownero, and Bitcoin prices across 6 exchanges in real time.",
color: "yellow",
},
{
slug: "webshops",
title: "Webshops",
@@ -61,6 +67,7 @@ const colorClasses: Record<string, string> = {
blue: "border-blue-500/30 hover:border-blue-500/60",
pink: "border-pink-500/30 hover:border-pink-500/60",
orange: "border-orange-500/30 hover:border-orange-500/60",
yellow: "border-yellow-500/30 hover:border-yellow-500/60",
};
const titleColors: Record<string, string> = {
@@ -70,6 +77,7 @@ const titleColors: Record<string, string> = {
blue: "text-blue-600 dark:text-blue-400",
pink: "text-pink-600 dark:text-pink-400",
orange: "text-orange-600 dark:text-orange-400",
yellow: "text-yellow-600 dark:text-yellow-400",
};
export default function ProductsPage() {
@@ -64,7 +64,17 @@ export const PortfolioGrid = () => {
</Card>
</Link>
{/* Row 2: Privacy Labs (1x1) */}
{/* Row 2: Neroswap (1x1) */}
<Link href="https://neroswap.com" target="_blank" rel="noopener noreferrer" className="md:col-span-1">
<Card className="h-full glass-card group min-h-[300px] rounded-[2.5rem] !bg-yellow-50/95 dark:!bg-yellow-950/95 !border-yellow-500/20 cursor-pointer">
<div className="absolute inset-x-0 top-0 z-20 p-6 bg-gradient-to-b from-background/95 to-transparent pointer-events-none">
<h3 className="text-xl font-bold text-yellow-700 dark:text-yellow-400">Neroswap</h3>
<p className="text-sm mt-1 text-foreground font-semibold">DEX &amp; CEX orderbook aggregator.</p>
</div>
</Card>
</Link>
{/* Row 2-3: Privacy Labs (1x1) */}
<Link href="https://play.wowne.ro" target="_blank" rel="noopener noreferrer" className="md:col-span-1">
<Card className="h-full glass-card group min-h-[300px] rounded-[2.5rem] !bg-orange-50/95 dark:!bg-orange-950/95 !border-orange-500/20 cursor-pointer">
<div className="absolute inset-x-0 top-0 z-20 p-6 bg-gradient-to-b from-background/95 to-transparent pointer-events-none">