TaskMarket
A Toronto marketplace for owned local data. Restaurants, landlords and other owners sell aggregated data about their own business, buyers see a sample first, and every delivery is checked against a schema and a privacy floor before payment settles. Backend rewritten in Rust.
Context
TaskMarket started as a task marketplace for international students, with USDC escrow on Base. In September 2026 I refocused it around one question: can the settlement be checked by code? For errands it mostly can’t. For data it can, because a delivery either matches the agreed schema and privacy rules or it doesn’t.
So TaskMarket is now a Toronto marketplace for owned local data. A restaurant, a landlord or a driver sells aggregated data about their own business. Buyers see a sample before they pay, and nothing settles until the delivery passes an automatic check. Scraped data is out of scope; only the owner of the data can list it.
Screenshots are 3840×2160, as on a 32-inch 4K monitor. The data-market screens come from a local instance seeded with the project’s synthetic sample products, labelled as samples. The task screens come from the live site, where open tasks are generated examples.
Approach
Settlement that code can verify
Every listing carries a JSON Schema and an aggregation floor, for example “every row must cover at least five stores”, so no single business can be identified. After the buyer pays (by invoice or USDC), the seller uploads the delivery as JSON or CSV:
- The rows are validated against the schema with Ajv, and the floor is checked row by row.
- Pass: the order settles and the buyer can download the file.
- Fail: the delivery is rejected with row-level errors, and the seller can fix it and deliver again.
- Each delivery is stored with a SHA-256 hash of its payload, and delivery files are only downloadable by the buyer, never as public static files.
Sellers sign a consent template with their wallet before listing, and revoking it takes their listings down.
Collection tasks for the gaps
Where data doesn’t exist yet, it can be collected in person. The original task marketplace became collection tasks in seven categories: footfall counts, storefront checks, mystery shopping, surveys, price checks, verification and street promotion. Tasks still run on a bid book, so the poster compares price, timing and track record instead of taking the first reply, and USDC payments can still go through the escrow contract on Base.
A Rust backend, proven against the old one
I rewrote the Express backend in Rust (axum, sqlx, socketioxide) as a drop-in replacement: same database, same JSON, same Socket.IO events, so the front end did not change. The old Node code served as the spec:
- A parity harness replays 933 scenarios against both servers and compares status codes and bodies, plus 48 Socket.IO checkpoints.
- Before the switch, the Rust server answered live endpoints identically on a copy of the production database.
- It went live on September 10, 2026, behind a one-line flag that can switch back to Node.
The only intended behaviour change was a fix: an order could previously be auto-confirmed after it had been cancelled or disputed, which could have released escrowed funds.
Fast public pages
The public routes are server-rendered on Cloudflare Pages Functions, with structured data that marks each listing as a Dataset. Splitting the bundle cut first-load JavaScript from 257 KB to 122 KB gzipped, and wallet code now loads only when someone opens a wallet flow.
Results & What I Learned
Live at taskmarket.pages.dev. The data market is open. It deliberately starts empty, because sample listings don’t belong in a market that promises real data. A pilot with local restaurants started in September 2026.
- Choose a market where settlement can be verified. Disputes are the expensive part of any marketplace. A schema and a privacy floor turn “was this good enough?” into a check that runs in milliseconds.
- Rewrite against a parity harness, not against memory. The old server was the specification. 933 replayed scenarios made the switch a configuration change rather than a leap of faith, and surfaced one real money bug along the way.
- An empty shelf beats a fake one. Seeding demo listings would make the market look busier and make every listing less believable.
Tech Stack & Links
Front end: React 19 · Vite 7 · Tailwind 4 · Cloudflare Pages Functions (SSR)
Back end: Rust · axum · sqlx · SQLite · socketioxide · Ajv (delivery validation)
On-chain: Solidity escrow on Base · viem
Live: taskmarket.pages.dev