feat: Implement Skywire Decentralized Exchange (Exchange Market & Client)#3434
Merged
Conversation
Collaborator
|
@mrpalide note that there are a few repos that you might want to look at which already did a lot in this general direction. I think they were designed for a centralized model, but might still be relevant. https://github.com/skycoin/skycoin-exchange |
…que non-round payment amounts
…-timed SKY refund
…ount buyer cancels as freeze violations
…d amount precision/bounds
…d) + raise node read cap to 32MiB
… white-text badges, operator unban + clear-block controls, configurable buy-cancel limit (min 2)
…join, per-item delete, and clear-all (localStorage)
… instead of stuck on connecting (no idle skywire connection to infer status from)
…der and recent-markets list — piggybacked on get_currencies, no new round-trip
… and hide the My-Listings Cancel button once a buyer has selected the product (backend now reports cancelable/product_status)
amount (BIP-21 for BTC/LTC/DOGE/DASH/BCH/SKY, address-only fallback), shown in both buy and sell flows
… app list, and make escrow secrets write-only
…ed attempt, and give session tokens their own alphabet
buildTransitDmsg added all of deployment.Prod's dmsg servers to the transit client unconditionally, so a private or e2e deployment opened sessions to the nine public production servers on every start. Those dials sit on the cold-start path and competed with the registration the function exists to enable — visible in CI e2e logs as sessions to prod PKs and a connection refused to 143.42.59.213:30088. Seed per discovery PK instead, via a new EmbeddedServersForDiscoveryPK that the existing URL-keyed EmbeddedServersForDiscoveryDmsg now delegates to, so both paths share one coupling guarantee. Production servers are unaffected; only foreign deployments stop dialing the fleet. Adds the deployment package's first tests, pinning that the e2e discovery gets nil.
Binaries and app names become skydex-market / skydex-client, display names "SkyDEX - Market" / "SkyDEX - Client". Renames the cmd/apps and internal trees, skyenv constants, Makefile targets and the CI job, and rebuilds both UIs — the Angular manager hardcodes the app name for the OTP column, so its bundle had to be regenerated too. The operator OTP is now five digits instead of five alphanumerics, and any wrong entry burns the code rather than only the tenth. That shrinks the space to 100_000, so globalLoginRefill goes 6s -> 6m: 240 attempts/day puts covering the space at ~417 days, and a single operator is still covered by the burst of ten. Session tokens get their own alphabet so OTP ergonomics can no longer weaken them.
The SkyDEX engine now lives in github.com/skycoin/skycoin (src/skydex/*, cmd/skydex-*) with no skywire dependency, mirroring skycoin-web. Skywire keeps only the transport wrapper (~600 LOC, down from ~14k):
- cmd/apps/skydex-{market,client}: supply the appnet/dmsg transport and delegate to the skycoin engine. The market Listens on appnet.TypeDmsg and injects each client's authenticated dmsg public key as its identity (via IdentifyFunc); the client dials the market's public key over dmsg (via MarketDialer). Business logic is reached through the engine's Host / MarketDialer seams.
- internal/skydex-{market,client}/app: the visor app.Client wrappers (kept).
- internal/skydex-e2e: the real dmsg wire test, now driving the skycoin engine over an in-process dmsg mesh — still passes.
- Removed the engine packages, operator/trading UI, and React sources that moved to skycoin.
- protocol.Port dropped its routing.Port alias (now uint16) so the engine has no skywire tie.
mrpalide
marked this pull request as ready for review
July 20, 2026 15:31
0pcom
added a commit
to 0pcom/skywire
that referenced
this pull request
Jul 20, 2026
Refresh vendored github.com/skycoin/skycoin to develop HEAD. Rebased onto current skywire develop (post exchange/skydex merge skycoin#3434).
0pcom
added a commit
that referenced
this pull request
Jul 20, 2026
Refresh vendored github.com/skycoin/skycoin to develop HEAD. Rebased onto current skywire develop (post exchange/skydex merge #3434).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Did you run
make format && make check? YesOverview
This PR is the Skywire half of the SkyDEX decentralized-exchange ecosystem: two thin visor apps —
skydex-marketandskydex-client— that carry the exchange over a Skywire dmsg transport using the visor's app networking. The exchange engine itself — the dmsg protocol, SQLite state, escrow, background jobs, local-signed blockchain settlement, the operator UI, and the React trading client — now lives in the skycoin repo (src/skydex/*,cmd/skydex-*) and carries zero skywire dependency. See the companion PR skycoin/skycoin#. This mirrors how skywire wraps skycoin-web: domain logic in skycoin, networking as a drop-in skywire reconfiguration.The market sells SKY and any operator-added Skycoin fibercoin — each coin is add/edit/enable/disable/delete-able with its own fullnode + escrow hot wallet — against external UTXO coins (BTC/LTC) or another fibercoin. Users are identified solely by their Skywire public key. Payments are auto-verified against the recipient wallet — no transaction hash required from users: sell-coin/fibercoin transfers by sender address + time window + fixed amount, external UTXO payments (BTC/LTC) by a unique non-round amount + time window. Sell-coin delivery and refunds are signed locally from an operator seed and broadcast via that coin's Skycoin-family node (the node's wallet API is never used).
Repo split
src/skydex/{protocol,message,db,chain,jobs,walletaddr,server,market}(the engine) +cmd/skydex-market/cmd/skydex-client(standalone TCP reference commands, operator/auth UI, React client). No skywire import.cmd/apps/skydex-{market,client}: the transport wrapper that Listens/Dials over appnet dmsg, injects the authenticated public key as identity, and hands anet.Listener/net.Connto the engine. Plus app registration in config-gen and the two-visor dmsg-mesh E2E.Implementation Status
✅ In this PR (skywire — transport wrapper)
cmd/apps/skydex-clientandcmd/apps/skydex-market, registered in themerged
skywirebinary and emitted in generated visor configs (routing ports 8050/8051;--addr/--porton both,--market-pk/--market-porton the client).appnet.TypeDmsgvia the visor and injects eachclient's authenticated dmsg remote public key as the identity (
server.IdentifyFunc), thendelegates to the engine's
Run. No bespoke dmsg server — uses app networking.MarketDialer) andhands the framed connection to the engine.
internal/skydex-{market,client}/app(theapp.Clientwrappers) and theengine
Host/MarketDialeradapters — operator OTP → visor app list, market identity → visor PK.internal/skydex-e2e, scripted chain) driving the skycoin engineover a real in-process dmsg mesh; plus a guided
livenet-tagged live harness.✅ In the companion skycoin PR (the engine — no skywire dependency)
src/skydex/protocol) — register,get_currencies, get_products, create_listing, buy_product, cancel_listing, cancel_order, get_orders,
get_order_status, get_listings; framed with
src/skydex/message(a copy of skywire'spkg/skychat/message). The server is transport-agnostic:Accept(ctx, net.Listener, IdentifyFunc)ServeConn(conn, identity); single-session enforcement per identity.src/skydex/db) withauto-migrations — 8 tables + full CRUD, thread-safe; default config (commission, confirmations,
trade limits, timeouts, ban rules, per-coin explorers, sell-coin registry).
:8050): configuration (commission rate/floor/cap, confirmations,min/max trade size, ban rules), the sell-coin registry (add/edit/enable/disable/delete SKY +
fibercoins, each with its own node URL, escrow seed/address and confirmation depth), per-coin
explorer enable/disable, and monitoring (products, orders, bans, commission), behind a localhost
operator API gated by a one-time code the app publishes to its host (the visor app list over
skywire). The UI is parameterized by a 3-method
Host(Log / PublishOTP / PubKey).sell_coinstable (SKY is the seeded, editabledefault), a per-symbol chain router, coin-generic wire/DB/UI. One registered address receives
every fibercoin a user buys.
that coin's node by sender + window + fixed amount; external UTXO coins keep the unique
non-round amount.
Runner: Expiry Handler, Listing Checker, Escrow Checker,Return Scheduler (immediate refund), Ban Manager, Cleanup Job, Escrow Audit (per sell coin).
src/skydex/chain): local-signed sell-coin settlement (read UTXOs/api/v1/outputs, sign in-process viasrc/coin+src/cipher+src/transaction, broadcast via/injectTransaction); deposit & payment verification by address + window + exact amount; pluggableper-coin explorer adapters (Esplora live-validated for BTC/LTC). Live-verified on SKY mainnet.
clamp(amount × rate%, min, cap), folded into the seller's deposit.embed.FSincmd/skydex-client: connect gate → Market / My Orders / My Listings / Settings; sell-coin +payment-currency selection; live
get_order_statuspolling (confirmations/tx-hash, commissionbreakdown, cancel buttons).
escrow/DB consistency audit, operator-configurable confirmations and trade size.
livenet-tagged) — deposit → buy → pay → deliver against the liveSKY node + Esplora, local-signed SKY delivery, commission retained; on-chain verified.
livenetlive checks), the sell-coin registry, fibercoin-payment routing, and both apps' HTTP APIs.🚧 TODO / Pending
adapter but not yet validated end-to-end; they'll be enabled after feedback + testing.
Account/token chains (USDT ERC-20/TRC-20, ETH) need per-contract endpoints and are future work.
(XMR intentionally unsupported — not verifiable by address.)
its TCP remote address; a real standalone auth (TLS client cert / blockchain login) is a follow-up.
Over skywire the identity is the authenticated dmsg public key (already in place).
Notes
dmsg transport + identity injection + config-gen registration.
wallet API is never touched (the escrow seed stays in-process).
UTXO coin (BTC/LTC) or another fibercoin (fixed amount, verified on its node).
considered and dropped as low-value/uncontrollable).
modernc.org/sqlite(pure-Go, CGO-free — matches the repo'sCGO_ENABLED=0static, cross-compiled builds); all timestamps stored as UTC.
auto-deleted after 3 days).
transactions — no user-submitted transaction hashes.