Pre-alpha · Spec first · No token

Soko

Commerce without a marketplace. A keypair is a store.

Soko is the reference implementation of TRACT — an open protocol for decentralized commerce covering goods, services, rentals and subscriptions between self-sovereign identities. Your catalogue is a signed feed you publish, not rows in someone's database. Your cart lives on your own devices. Delivery is computed locally from published rate cards rather than brokered by a platform. Nobody can delist you, and leaving costs a DNS change.

A Soko storefront rendering six listings of different shapes — a notebook, a workshop, a scaffold hire, a font licence, a made-to-measure apron and a bulk quote — all the same offer object

Six listings, one object model — no product type, no booking module, no rentals plugin. Rendered by soko-storefront from real catalogue objects. It does not yet fetch from a feed, verify a signature, or take an order.

What changes when there is no operator

Every row below is something a platform currently owns on your behalf.

Your catalogue is yours

A store is a signed, append-only feed published from a keypair. There is no account to be suspended and no operator who can edit, reorder or remove your listings. Delisting is not a permission anyone holds.

One product, many sellers

A product record is content-addressed, so two sellers publishing the same record converge on the same address by construction — no GS1 fee, no ASIN, no registrar. Where this is still unproven →

Manufacturers sign their own facts

A brand can sign the canonical record for its own product, so a reseller adds an offer but cannot misdescribe the thing. On a centralized marketplace, the marketplace is authoritative about your product. Here you are.

The cart is the buyer’s

Cart, wishlist and purchase history are CRDT state on the buyer’s own devices, synced across them and surviving any store closing. A merchant never sees what else you are considering, because there is no shared session to see it in.

One cart, independent sellers

Assemble a cart spanning sellers who have never heard of each other and check out once — including bundles whose components come from different sellers. A platform structurally cannot do this; separate stores mean separate checkouts.

Delivery computed, not brokered

Carriers, distributors and peer couriers publish rate cards as signed public objects. Routing and consolidation are computed on the buyer’s node — no quote API, no rate limit, no middleman learning what you are shopping for.

One shape for every trade

Goods, services, rentals, bookings and subscriptions are the same object with four axes — not a plugin per category.

Item

product · variant-of-group · service · right or licence · capacity. Variants follow the schema.org ProductGroup / variesBy model, so existing feeds map in.

Availability

count · time slots · capacity per interval · unlimited · made-to-order. Slots profile VAVAILABILITY from RFC 5545 rather than inventing a calendar.

Fulfilment

ship · collect · digital grant · perform-at-place · perform-remote · access grant · return-required. This axis is also what determines place of supply for tax.

Consideration

fixed · tiered/volume · recurring · metered · deposit + balance · quote-required. B2B contract pricing and RFQ are first-class, not an enterprise add-on.

Four small closed sets, combined. That is enough to express a haircut booking, a scaffolding hire, a made-to-measure suit, a metered API, and a tin of beans — without a category-specific code path for any of them.

Soko implements TRACT; TRACT stands on DMTAP

Nothing here reinvents identity, feeds, sync, or reachability — those are the DMTAP substrate, adopted unchanged.

# the spec is the product; read it first
git clone https://github.com/vul-os/tract
cd tract && make lint

# the implementation
git clone https://github.com/vul-os/soko
cd soko && cargo check --workspace

# settlement names no provider — wire your own
# cargo tree -p soko-seam  ->  one line, zero deps
  1. 1
    SubstrateIdentity, Feeds & Blobs, Sync, Infrastructure Roles and Wake come from DMTAP under its à-la-carte adoption rule — implement a capability's function, speak its spec.
  2. 2
    SpineTRACT adds only commerce: catalogue, offer, cart, order, delivery, settlement, trust. No new cryptography, no new hash construction, no new signature framing.
  3. 3
    SeamsWhere a real institution must be chosen — who settles money, who holds goods in dispute — TRACT specifies a seam and refuses to name a provider. Naming one exports its jurisdiction to every implementor.

How it fits together

The storefront above is the one rendered surface. These describe the structure behind it, regenerated from source rather than hand-drawn.

One cart across independent sellers

Each seller publishes a signed feed; any node may index them and none is authoritative. The buyer’s node assembles one cart and sends a separate sealed order to each seller, so no party sees the whole cart.

The four axes of an offer

Every trade is one object with four axes. The dotted edge is the one that catches people out: fulfilment also derives place of supply, which is the tax anchor — an event held abroad is taxed at the venue no matter where either party lives.

Checkout across independent sellers

The buyer’s node orchestrates; there is no central checkout. The gateway appears only if both parties chose escrow.

What Soko does not remove

A decentralized design that hides its operator classes is lying about them. TRACT has one, and says so on the first page. The closest thing to this that actually shipped — OpenBazaar — died in 2021 having moved about $86k in 14 months; the spec records why, in detail, rather than omitting it.

Somebody renders the store

A shopper with no keypair cannot verify a signature, so they trust a storefront gateway to have rendered honestly. Unlike DMTAP's mail gateway, this one never self-extinguishes — browsers are permanent. Any node can re-render the same store and be compared byte-for-byte; that bounds the trust, it does not remove it.

Somebody holds the money

Holding funds for strangers is a licensed activity nearly everywhere. Escrow is an operator class: permissionless to enter, competing, chosen per-order by both parties, scoped to the jurisdictions it is actually licensed for — and never in possession of anyone's identity keys. Its every ruling is a signed public object, so unfair operators accumulate a permanent record of it.

Nobody agrees on a star rating

Reviews are signed and proven against real purchases, which makes ballot-stuffing cost a real transaction. But ranking is derived data any node computes, so different indexes will rank differently. There is no canonical 4.7 stars, because computing one requires an authority — and that is the thing being removed.

Part of Vulos

Soko is one of a family of open, self-hostable products that stand alone but compose — Envoir for mail and identity, Ofisi for documents, SlipScan for books, OpenRate for exchange rates, Patala for payment rails. Same substrate, same posture: your data on your machine, no telemetry, and an honest statement of what each one cannot do.

Explore Vulos →