solisting
Vision
Today's marketplaces are gatekept: a company can delist a product, freeze a seller's payout, or shut down the platform outright, and buyers/sellers have no recourse. solisting is built on the belief that product listings and the payments behind them should live on-chain instead — where no single operator can censor a listing, and no middleman sits between buyer and seller taking a cut or holding custody.
- 🌍 Decentralized marketplaces — listings and orders live as on-chain accounts, not rows in a company's database, so there's no central operator who can arbitrarily delist products or gatekeep who gets to sell.
- 🚫 No middleman — buyers and sellers interact directly through the protocol; there's no platform sitting between them extracting fees, controlling access, or acting as a single point of failure.
- 🧱 Censorship-resistant listings — as long as the underlying blockchain is live, a listing exists and stays visible; it can't be quietly taken down by a platform decision.
- ✅ Final, auditable payments — every payment flows through smart contract escrow, so settlement is final and every step of it is publicly verifiable on-chain, not hidden inside a company's internal ledger.
- 🔮 Predictable by construction — the rules for how funds move (when they're locked, when they're released, when they're refunded) are enforced by code, not discretionary platform policy, so outcomes are known in advance rather than decided case-by-case.
What is solisting?
solisting is a single-program Solana protocol that implements a coordination and discovery layer for decentralized product listings and bilateral order consent. It sits on top of a separate escrow program, descro, and never custodies funds itself — it CPIs into descro to create, confirm, and cancel escrows.
Built using Anchor.
The repository also contains a TypeScript SDK and a Next.js explorer app built on top of the on-chain program.
Concept
Marketplaces on Solana usually force a choice: either the marketplace program custodies funds itself (more trust assumptions, more surface area to audit), or every integration reinvents escrow from scratch. solisting takes a different approach — it is a thin coordination layer that only handles discovery (listings) and consent (orders), and delegates all fund custody to a dedicated, independently auditable escrow program (descro) via CPI.
- 🔐 Non-custodial by design — solisting never holds buyer or seller funds; every escrow lifecycle event is a CPI into
descro, so the fund-custody logic lives in one focused, auditable program instead of being duplicated per marketplace. - 🧩 Composable, not monolithic — separating listings/orders from escrow means
descrocan be reused by other marketplace front-ends, andsolistingcan evolve its discovery/consent UX independently of settlement logic. - 💱 Multi-currency listings from one source of truth — a seller sets a single canonical price; buyers can pay in alternate currencies (including SOL or stablecoins) and the program converts on the fly via Pyth oracles, so there's no need to maintain N parallel prices per listing.
- 🛡️ Slippage-protected conversion — buyers supply an expected amount and max slippage tolerance, so oracle-based conversion can't silently overcharge them between quote and execution.
- 🤝 Bilateral consent, defensively handled — orders require explicit seller acceptance, and abort paths (
reject_order/cancel_order) tolerate the counterparty already having cancelled directly ondescro, avoiding stuck states.
Repository layout
programs/solisting/ # Anchor program (Rust)
sdk/ # TypeScript client SDK (Codama-generated + hand-written helpers)
app/ # Next.js app for browsing listings/orders
docs/ # Implementation plans and design docs
vendor/ # Vendored/patched Pyth crates (see "Toolchain gotchas" below)
Architecture
Canonical price model
ListingAccount stores one canonical price (canonical_currency + price) as the sole source of truth:
alt_currencies— other currencies a buyer may pay in, each with an optional PythTOKEN/USDoracle (None= treated as a $1.00 stablecoin).canonical_oracle— the Pyth feed for the canonical currency (None= canonical is itself a $1 stablecoin).
At create_order time, if the buyer pays in an alt currency, the program converts the canonical price into the target currency using USD as a pivot through up to two Pyth feeds, and enforces a buyer-supplied slippage tolerance.
Accounts & PDAs
ListingAccount— seeds[b"listing", seller, listing_id]. Tracks quantity, reservations, accepted resolvers, active state, and metadata URI.OrderAccount— seeds[b"order", listing_account, buyer, order_id]. Records the buyer's chosen payment currency, the oracle-resolved amount, and a pointer to the correspondingdescroEscrowAccount.
Instructions
| Instruction | Purpose |
|---|---|
create_listing / update_listing / close_listing |
Manage a listing (seller-only) |
create_order |
Buyer flow: validates currency/resolver, performs oracle conversion, CPIs into descro to create an escrow |
accept_order |
Seller flow: confirms the escrow and settles the listing's reserved quantity |
reject_order / cancel_order |
Seller/buyer-initiated abort, defensive against out-of-band cancellation on descro |
close_stale_order |
Permissionless cleanup of orders whose escrow has already reached a terminal state |
Prerequisites
- Rust toolchain
1.89.0(pinned viarust-toolchain.toml) - Solana CLI /
cargo build-sbf - The sibling
descrorepository checked out at../descrorelative to this repo — solisting path-depends on it and the tests embed its compiled.sofiles. - Node.js + Yarn (for the SDK and app)
Building
descro (and its dependency descro_ext_resolvers) must be built first:
# 1. Build dependency programs (sibling repo)
cd descro && anchor build
# 2. Build solisting
anchor build
Testing
Requires steps 1 + 2 above to have been run first, since the LiteSVM test harness embeds both .so files via include_bytes!:
cargo test --manifest-path programs/solisting/Cargo.toml
# Run one test file / one test by name
cargo test --manifest-path programs/solisting/Cargo.toml --test test_orders
cargo test --manifest-path programs/solisting/Cargo.toml -- seller_can_create_sol_only_listing
Lint / format
cargo clippy --manifest-path programs/solisting/Cargo.toml
cargo fmt --manifest-path programs/solisting/Cargo.toml
Note: Anchor.toml declares test = "cargo test", but anchor test is not the normal workflow here — use the cargo commands above directly.
SDK & app
The sdk/ and app/ workspaces are managed with Yarn:
yarn install
yarn workspace @solisting/sdk ... # SDK-specific commands
See their respective package.json files and docs/superpowers/ for details on the SDK and explorer app.
Toolchain gotchas
- The Rust toolchain is pinned to
1.89.0viarust-toolchain.toml. - The workspace root
Cargo.tomlpatchespyth-solana-receiver-sdkandpythnet-sdkto local copies undervendor/because the crates.io versions don't compile against this toolchain's dependency graph (ananchor-lang/borshversion conflict). If you touch oracle code, the vendored crates are the source of truth forPriceUpdateV2's shape.