# Silhouette > Silhouette is a shielded trading platform on Hyperliquid. Trade without exposing your wallet, your strategy, or your size. The cheapest venue to accumulate assets onchain. - [Silhouette](https://docs.silhouette.exchange/index.md) ## about-silhouette Silhouette is the universal block trading layer on Hyperliquid. Request quotes from competing market makers and execute size in one trade, across HyperCore and HyperEVM. - [Introduction](https://docs.silhouette.exchange/about-silhouette.md): Silhouette is the universal block trading layer on Hyperliquid. Request quotes from competing market makers and execute size in one trade, across HyperCore and HyperEVM. ## quickstart ### makers Start quoting RFQs on Silhouette. Mint API credentials, discover open requests, submit competing quotes, and settle the trades you win. - [Quickstart for Makers](https://docs.silhouette.exchange/quickstart/makers.md): Start quoting RFQs on Silhouette. Mint API credentials, discover open requests, submit competing quotes, and settle the trades you win. ### takers Place your first RFQ on Silhouette. Connect a wallet, deposit funds, request quotes from competing market makers, and settle the trade on-chain. - [Quickstart for Takers](https://docs.silhouette.exchange/quickstart/takers.md): Place your first RFQ on Silhouette. Connect a wallet, deposit funds, request quotes from competing market makers, and settle the trade on-chain. ## trading ### fees Silhouette Exchange fee structure for naked and shielded trading on Hyperliquid. Transparent builder code fees and dynamic shielded savings. - [Fees](https://docs.silhouette.exchange/trading/fees.md): Silhouette Exchange fee structure for naked and shielded trading on Hyperliquid. Transparent builder code fees and dynamic shielded savings. ### naked-trading Naked trading on Silhouette routes orders directly to Hyperliquid via Builder Codes. Full visibility, full order type support across spot and perpetuals. - [Naked Trading](https://docs.silhouette.exchange/trading/naked-trading.md): Naked trading on Silhouette routes orders directly to Hyperliquid via Builder Codes. Full visibility, full order type support across spot and perpetuals. ### order-lifecycle Follow the complete lifecycle of shielded and naked orders on Silhouette Exchange, from submission through TEE processing to Hyperliquid settlement. - [Order Lifecycle](https://docs.silhouette.exchange/trading/order-lifecycle.md): Follow the complete lifecycle of shielded and naked orders on Silhouette Exchange, from submission through TEE processing to Hyperliquid settlement. ### shielded-trading Shielded spot trading keeps your orders, identity, and strategy private while you trade on Hyperliquid's full spot order book. - [Shielded Spot Trading](https://docs.silhouette.exchange/trading/shielded-trading.md): Shielded spot trading keeps your orders, identity, and strategy private while you trade on Hyperliquid's full spot order book. ## glossary Glossary of terms used in Silhouette documentation: RFQ, takers, makers, quote windows, settlement, and Hyperliquid concepts. - [Glossary](https://docs.silhouette.exchange/glossary.md): Glossary of terms used in Silhouette documentation: RFQ, takers, makers, quote windows, settlement, and Hyperliquid concepts. ## faq Frequently asked questions about RFQ trading on Silhouette: instruments, quotes, settlement, funds, and API access. - [FAQs](https://docs.silhouette.exchange/faq.md): Frequently asked questions about RFQ trading on Silhouette: instruments, quotes, settlement, funds, and API access. ## blog Research, guides and dispatches on shielded trading, TEE-attested execution, and building privacy-preserving markets on Hyperliquid. - [Blog](https://docs.silhouette.exchange/blog.md): Research, guides and dispatches on shielded trading, TEE-attested execution, and building privacy-preserving markets on Hyperliquid. ### hyperliquid Why Silhouette built on Hyperliquid: an EVM-compatible L1 with the speed, scale and matching engine depth to support shielded trading at institutional size. - [Why We Chose Hyperliquid](https://docs.silhouette.exchange/blog/hyperliquid.md): Why Silhouette built on Hyperliquid: an EVM-compatible L1 with the speed, scale and matching engine depth to support shielded trading at institutional size. ### intro Silhouette is a shielded trading platform on Hyperliquid. Your orders stay private, your strategy stays yours, and the matching engine lives in a TEE. - [Introducing Silhouette](https://docs.silhouette.exchange/blog/intro.md): Silhouette is a shielded trading platform on Hyperliquid. Your orders stay private, your strategy stays yours, and the matching engine lives in a TEE. ### problemwithdefi Part one of the Silhouette shielded trading series. Why radical transparency in DeFi is an attack surface: strategy leakage, copytrade exposure, adverse selection. - [The Problem with DeFi, Transparency as an Attack Surface](https://docs.silhouette.exchange/blog/problemwithdefi.md): Part one of the Silhouette shielded trading series. Why radical transparency in DeFi is an attack surface: strategy leakage, copytrade exposure, adverse selection. ### problemwithprivacy Part two of the Silhouette shielded trading series. Why full-darkness privacy solutions (mixers, shielded L1s, early dark pools) broke DeFi and what to build instead. - [The Privacy Mirage - Why Complete Darkness Breaks DeFi](https://docs.silhouette.exchange/blog/problemwithprivacy.md): Part two of the Silhouette shielded trading series. Why full-darkness privacy solutions (mixers, shielded L1s, early dark pools) broke DeFi and what to build instead. ### redefiningdefi Silhouette closes a seed round led by RockawayX to build shielded trading on Hyperliquid. Strategies stay private, the orderbook stays public, the execution stays fast. - [Redefining DeFi with Silhouette](https://docs.silhouette.exchange/blog/redefiningdefi.md): Silhouette closes a seed round led by RockawayX to build shielded trading on Hyperliquid. Strategies stay private, the orderbook stays public, the execution stays fast. ### shielded-spot-trading Shielded spot trading is live on Hyperliquid. Execute HYPE/USDC orders through a TEE-attested matching engine with zero strategy leakage and 95% passthrough on the HL fee discount. - [Shielded Spot Trading - Live on Hyperliquid](https://docs.silhouette.exchange/blog/shielded-spot-trading.md): Shielded spot trading is live on Hyperliquid. Execute HYPE/USDC orders through a TEE-attested matching engine with zero strategy leakage and 95% passthrough on the HL fee discount. ### tokenised-stocks-wont-trade-where-you-think Issuer flow cannot use onchain order books. Why tokenised equities trade on RFQ first, what TradFi's off-exchange data proves, and why demand discovery precedes price discovery. - [Tokenised Stocks Won’t Trade Where You Think](https://docs.silhouette.exchange/blog/tokenised-stocks-wont-trade-where-you-think.md): Issuer flow cannot use onchain order books. Why tokenised equities trade on RFQ first, what TradFi's off-exchange data proves, and why demand discovery precedes price discovery. ### why-dark-pool-havent-worked Part three of the Silhouette shielded trading series. Onchain dark pools promised privacy and delivered liquidity deserts. Why they failed and how shielded trading fixes it. - [Why Dark Pools Haven’t Worked Onchain](https://docs.silhouette.exchange/blog/why-dark-pool-havent-worked.md): Part three of the Silhouette shielded trading series. Onchain dark pools promised privacy and delivered liquidity deserts. Why they failed and how shielded trading fixes it. ## brand Silhouette's brand kit — logos, colour, typography, and usage. Download the marks and use them correctly. - [The Silhouette Brand](https://docs.silhouette.exchange/brand.md): Silhouette's brand kit — logos, colour, typography, and usage. Download the marks and use them correctly. ## fees Silhouette RFQ fee schedule. 5 bps all-in on spot, 1.4 bps on perpetuals, published per instrument. - [Fees](https://docs.silhouette.exchange/fees.md): Silhouette RFQ fee schedule. 5 bps all-in on spot, 1.4 bps on perpetuals, published per instrument. ## rfq ### api The Silhouette RFQ API: REST and WebSocket access to request-for-quote trading. SIWE login, HMAC-signed requests, and OpenAPI/AsyncAPI specifications. - [RFQ API](https://docs.silhouette.exchange/rfq/api.md): The Silhouette RFQ API: REST and WebSocket access to request-for-quote trading. SIWE login, HMAC-signed requests, and OpenAPI/AsyncAPI specifications. - [Silhouette Docs](https://docs.silhouette.exchange/rfq/api/reference.md) - [Your first trade](https://docs.silhouette.exchange/rfq/api/first-trade.md): A golden-path walkthrough of one RFQ trade as a taker: authenticate, stream updates over WebSocket, submit and accept over REST, watch it settle. - [RFQ REST API](https://docs.silhouette.exchange/rfq/api/rest.md): The RFQ REST API: RFQs, quotes, maker operations, balances, and funding over HMAC-signed HTTP. OpenAPI 3.1 spec and generated clients. - [RFQ WebSocket API](https://docs.silhouette.exchange/rfq/api/websocket.md): The RFQ WebSocket streaming API: topic subscriptions for live RFQ, quote, balance, and price updates. AsyncAPI 3.0 spec. ### market-making - [HyperCore Market Making](https://docs.silhouette.exchange/rfq/market-making/hypercore.md): Market-make HyperCore spot pairs and perpetuals on Silhouette: spot from deposited inventory or by promised spot-send, perps by matched execution of pre-signed orders. No contract to deploy. - [HyperCore Perpetuals](https://docs.silhouette.exchange/rfq/market-making/hypercore/perpetuals.md): Market-make HyperCore perpetuals on Silhouette: a quote carries a pre-signed post-only order and its cancel, the taker accepts with a pre-signed IOC, and Silhouette crosses the two on Hyperliquid's order book. - [HyperCore Spot](https://docs.silhouette.exchange/rfq/market-making/hypercore/spot.md): Quote and settle HyperCore spot pairs on Silhouette: inventory quotes that settle on Silhouette's books, promised quotes you deliver by spot-send, the cascade behind a promised win, and funding. - [xStocks Market Making](https://docs.silhouette.exchange/rfq/market-making/xstocks.md): Market-make Backed's tokenized US equities (TSLAx, AAPLx, SPYx) on Silhouette: two atomic settlement modes through a wrapper contract you deploy. - [Quoting xStocks](https://docs.silhouette.exchange/rfq/market-making/xstocks/quoting.md): The off-chain maker loop for xStocks on Silhouette: WebSocket frames, quote submission over REST, outcome tracking, cancellation, and price ladders. - [xStocks Settlement](https://docs.silhouette.exchange/rfq/market-making/xstocks/settlement.md): What Silhouette signs to settle an xStocks fill (the Permit2 witness authorization) and the wrapper contract the maker deploys to consume it. ### overview How RFQ trading works on Silhouette: takers, makers, quote windows, auto and manual acceptance, and the trade lifecycle. - [How RFQs Work](https://docs.silhouette.exchange/rfq/overview.md): How RFQ trading works on Silhouette: takers, makers, quote windows, auto and manual acceptance, and the trade lifecycle. --- # Full Documentation Content # Blog Writing on shielded trading, TEE architecture, and the road to private perps AllResearchGuidesExplainersProductAnnouncements [![Tokenised Stocks Won’t Trade Where You Think](/assets/images/tokenised-stocks-header-ad5759bdb874c2fa00cef73ce05a453a.png)](https://docs.silhouette.exchange/blog/tokenised-stocks-wont-trade-where-you-think.md) [Featured·●RESEARCH·20 MIN](https://docs.silhouette.exchange/blog/tokenised-stocks-wont-trade-where-you-think.md) ## [Tokenised Stocks Won’t Trade Where You Think](https://docs.silhouette.exchange/blog/tokenised-stocks-wont-trade-where-you-think.md) [Issuer flow cannot use onchain order books. Why tokenised equities trade on RFQ first, what TradFi's off-exchange data proves, and why demand discovery precedes price discovery.](https://docs.silhouette.exchange/blog/tokenised-stocks-wont-trade-where-you-think.md) [Chandler·AUG 20 2026](https://docs.silhouette.exchange/blog/tokenised-stocks-wont-trade-where-you-think.md) ## LATEST [●PRODUCT·3 MIN](https://docs.silhouette.exchange/blog/shielded-spot-trading.md) ### [Shielded Spot Trading - Live on Hyperliquid](https://docs.silhouette.exchange/blog/shielded-spot-trading.md) [Shielded spot trading is live on Hyperliquid. Execute HYPE/USDC orders through a TEE-attested matching engine with zero strategy leakage and 95% passthrough on the HL fee discount.](https://docs.silhouette.exchange/blog/shielded-spot-trading.md) [FEB 04](https://docs.silhouette.exchange/blog/shielded-spot-trading.md) [●RESEARCH·5 MIN](https://docs.silhouette.exchange/blog/why-dark-pool-havent-worked.md) ### [Why Dark Pools Haven’t Worked Onchain](https://docs.silhouette.exchange/blog/why-dark-pool-havent-worked.md) [Part three of the Silhouette shielded trading series. Onchain dark pools promised privacy and delivered liquidity deserts. Why they failed and how shielded trading fixes it.](https://docs.silhouette.exchange/blog/why-dark-pool-havent-worked.md) [AUG 12](https://docs.silhouette.exchange/blog/why-dark-pool-havent-worked.md) [●RESEARCH·3 MIN](https://docs.silhouette.exchange/blog/problemwithprivacy.md) ### [The Privacy Mirage - Why Complete Darkness Breaks DeFi](https://docs.silhouette.exchange/blog/problemwithprivacy.md) [Part two of the Silhouette shielded trading series. Why full-darkness privacy solutions (mixers, shielded L1s, early dark pools) broke DeFi and what to build instead.](https://docs.silhouette.exchange/blog/problemwithprivacy.md) [JUL 14](https://docs.silhouette.exchange/blog/problemwithprivacy.md) [●RESEARCH·4 MIN](https://docs.silhouette.exchange/blog/problemwithdefi.md) ### [The Problem with DeFi, Transparency as an Attack Surface](https://docs.silhouette.exchange/blog/problemwithdefi.md) [Part one of the Silhouette shielded trading series. Why radical transparency in DeFi is an attack surface: strategy leakage, copytrade exposure, adverse selection.](https://docs.silhouette.exchange/blog/problemwithdefi.md) [JUN 20](https://docs.silhouette.exchange/blog/problemwithdefi.md) [●ANNOUNCEMENTS·4 MIN](https://docs.silhouette.exchange/blog/redefiningdefi.md) ### [Redefining DeFi with Silhouette](https://docs.silhouette.exchange/blog/redefiningdefi.md) [Silhouette closes a seed round led by RockawayX to build shielded trading on Hyperliquid. Strategies stay private, the orderbook stays public, the execution stays fast.](https://docs.silhouette.exchange/blog/redefiningdefi.md) [JUN 10](https://docs.silhouette.exchange/blog/redefiningdefi.md) [●RESEARCH·3 MIN](https://docs.silhouette.exchange/blog/hyperliquid.md) ### [Why We Chose Hyperliquid](https://docs.silhouette.exchange/blog/hyperliquid.md) [Why Silhouette built on Hyperliquid: an EVM-compatible L1 with the speed, scale and matching engine depth to support shielded trading at institutional size.](https://docs.silhouette.exchange/blog/hyperliquid.md) [FEB 22](https://docs.silhouette.exchange/blog/hyperliquid.md) * [ANNOUNCEMENTS·JAN 22 2025](https://docs.silhouette.exchange/blog/intro.md) [Introducing Silhouette](https://docs.silhouette.exchange/blog/intro.md) --- # Why We Chose Hyperliquid February 22, 2025 · 3 min read [![Silhouette Team](/img/silhouette-team-avatar.png)](https://silhouette.exchange) [Silhouette Team](https://silhouette.exchange) Building the future of private trading ![Silhouette and Hyperliquid partnership banner showing stacked Silhouette and Hyperliquid wordmarks](/assets/images/hyperliquid-1a3b7301a0322283d4c6a2c88ed85218.png) ***TL;DR*** **Silhouette is building on Hyperliquid because the future of on-chain needs speed, scale and privacy.** For an introduction to Silhouette, please see [Introducing Silhouette](https://docs.silhouette.exchange/blog/intro.md). Silhouette's goal is straightforward: offering a decentralised and full-featured private trading system that does not compromise user experience. A downfall of many other private trading environments is a lack of liquidity. Hyperliquid provides this liquidity and opportunity to support Silhouette’s mission. ## Why Hyperliquid?[​](#why-hyperliquid "Direct link to Why Hyperliquid?") Hyperliquid is a purpose-built chain aiming to [‘house all finance’](https://hyperfoundation.org/). Its high performance, transaction speed, and robust liquidity create an effective and successful Decentralized Finance (DeFi) trading environment. Liquidity is the lifeblood of DeFi. Healthy and sustainable liquidity ultimately determines the viability of crypto-economic systems. Rather than bootstrapping liquidity, the Silhouette protocol will be directly tied to the Hyperliquid L1 and HyperEVM, giving users and developers a new way to use their in-place assets in an exceptionally liquid ecosystem. There is no need to set it up; use your wallet. There is no need to bridge; all traders' liquidity on Hyperliquid is available to use. As the chain aspires to address fragmentation, Hyperliquid has considered traders in its development with features including: * **Exceptional Performance**: Hyperliquid operates in milliseconds, meeting the demands of high-frequency and high-value trading. * **Robust Liquidity**: The platform supports sustainable liquidity, ensuring better pricing and lower slippage. * **EVM Compatibility**: Hyperliquid’s integration with EVM unlocks new possibilities, from leveraged trading to dApps with enhanced privacy. ### Hyperliquid’s roadmap[​](#hyperliquids-roadmap "Direct link to Hyperliquid’s roadmap") The future of Hyperliquid is as compelling as its initial offering. With a focus on expanding its ecosystem, especially the focus on EVM compatibility, there will be even more use cases. These include leveraged trading, aggregation, advanced UIs, and yield platforms - all of which can benefit from privacy enhancements offered by Silhouette. ## What Silhouette Brings to Hyperliquid[​](#what-silhouette-brings-to-hyperliquid "Direct link to What Silhouette Brings to Hyperliquid") Hyperliquid provides the foundation of performance and liquidity, while Silhouette brings a critical layer of privacy that enhances the trading experience for users. A key reason DEXs struggle with liquidity when compared to CEXs is because of the extra effort required for sophisticated actors to protect their proprietary strategies. For many traders and market makers, their order flow is their intellectual property. Silhouette’s privacy features ensure users can safeguard their strategies without sacrificing performance or liquidity. By enabling secure, private trading, Silhouette enhances the overall value proposition of Hyperliquid, making it the go-to choice for serious DeFi traders. ### Being Fit-For-Purpose[​](#being-fit-for-purpose "Direct link to Being Fit-For-Purpose") While we see ourselves as multi-chain in the future, our immediate focus is building a platform that is fit for purpose, and Hyperliquid makes this possible. Backed by real performance, liquidity, and neutrality, we can create a next level experience currently unavailable in DeFi. Users choose their trading venues for multiple reasons - the experience, the rewards, the community, and more. We want to enhance that experience and align with a chain that has a mission closely linked to ours - providing tools that make on-chain finance fairer and more valuable. ### Join Us Follow our journey and stay informed. * [](https://x.com/silhouette_ex) * [](https://silhouette.exchange/) * [](https://docs.silhouette.exchange/blog.md) * [](https://t.me/silhouette_exchange) --- # Introducing Silhouette January 22, 2025 · 4 min read [![Silhouette Team](/img/silhouette-team-avatar.png)](https://silhouette.exchange) [Silhouette Team](https://silhouette.exchange) Building the future of private trading ![Silhouette introduction banner with the Silhouette wordmark on a dark background](/assets/images/intro-2c94342984af0f7581bdcf7ec97d94a7.png) Silhouette is a decentralised trading platform that offers alternative trading types to the Hyperliquid ecosystem. Using the latest privacy technology, we provide a hidden matching engine to optimize trade executions. Submit and complete your trade without sharing your strategies with the market. ## DeFi and Privacy[​](#defi-and-privacy "Direct link to DeFi and Privacy") Private trading is an environment designed to keep specific trade details secret. It allows trading strategies to be executed discreetly without broadcasting every action. This concept is not new; it is a standard part of the traditional financial system, but it has not been successfully implemented in decentralised finance (DeFi). DeFi, as a fully open and transparent trade environment, is one of the most compelling financial innovations in recent times. But it’s not perfect or immune to problems. With such radical transparency comes ample opportunities for exploitation and negative trading practices. Information leak through decentralised exchanges open opportunities that diminish the value of the average trade, such as the well-known Maximal Extractable Value (MEV). This reduces the length of time an alpha-generating strategy can be useful. Even though traders know this limitation of DEX environments, few have switched to the existing DeFi private trading exchanges. This is partly because private technology for DeFi platforms often has a poor user experience, discouraging traders from continuing after battling to place simple trades. Liquidity also presents a challenge. It is well established that privacy for the sake of privacy is not a strong enough draw for DeFi traders. If a platform does not have adequate liquidity, traders won’t see value in keeping these low-quality trades private. We strongly believe that end-to-end privacy is a different product. Specifically, we are not designing our product to focus on privacy as the killer feature but on execution guarantees enabled by privacy. To build this valuable private trading environment, we bring together three key elements: Effective privacy: Protect trade details without compromising user experience High-quality strategies: Create the environment for trading strategies to last Liquidity: Leverage existing liquidity ## Bringing Private Trading to DeFi[​](#bringing-private-trading-to-defi "Direct link to Bringing Private Trading to DeFi") DeFi and traditional finance each have their own set of standards and drawbacks. Understanding the differences between these two markets is important, as transferring the offering from one market does not guarantee success in the other. Each market has its nuances and patterns. In traditional finance, private trading venues ensure back-channel order flow and avoid signalling large sales to the market. In DeFi, we like the idea of transparently knowing the state of the market. So, privately pushing orders as if we were a traditional private venue doesn't work. Instead, we see the application of privacy in strategies as more important. You can see the state of the market, but you can't see someone's specific strategy. An example can be seen in centralised exchanges (CEXs). These platforms have public, open-order books, but user account information and trades are private. This allows for some information protection on who places orders and their strategy, offering only the aggregate view of the market to on-lookers. ## Our Approach[​](#our-approach "Direct link to Our Approach") *Leveraging Liquidity* Our traders can use the native liquidity they have on-chain through Hyperliquid. Powered by the Central Limit Order Book, trades on Silhouette will feel like a private layer on top of Hyperliquid. *Diverse Trading Options* Our aim is not to replace the fully transparent DEXs but to act as another avenue for traders, diversifying what is possible and bringing more value to DeFi. Once privacy is on the table, traders can keep their views on the market secret, protect their leveraged positions, avoid front-running swaps, and not reveal a hedge. These are just a few of the trading benefits privacy opens up. ## Looking Ahead[​](#looking-ahead "Direct link to Looking Ahead") We’re working hard to build the foundations of the next generation of DeFi trading. In our next update, we’ll share why we chose Hyperliquid as our partner on this journey and details of our technical design outlining our trading environment. ### Join Us Follow our journey and stay informed. * [](https://x.com/silhouette_ex) * [](https://silhouette.exchange/) * [](https://docs.silhouette.exchange/blog.md) * [](https://t.me/silhouette_exchange) --- # The Problem with DeFi, Transparency as an Attack Surface June 20, 2025 · 4 min read [![Silhouette Team](/img/silhouette-team-avatar.png)](https://silhouette.exchange) [Silhouette Team](https://silhouette.exchange) Building the future of private trading ![The Problem with DeFi series header showing transparency as an attack surface](/assets/images/defi-problem-header-2e08cc700b737341c1e42688b88ee0d3.png) *Part one of a three-part series on the future of shielded trading.* Decentralized Finance (DeFi) is one of crypto’s boldest promises: an open, borderless financial system that anyone can access with nothing more than a wallet and an internet connection. And to be fair, it has delivered. DeFi protocols now hold over [$114 billion](https://defillama.com/) in value. Billions move daily through decentralized exchanges and perpetuals. Financial primitives like lending, swaps, and synthetic assets are now programmable and permissionless. But for all the technical achievement and excitement, DeFi is still stuck in a loop, haunted by the same issues that have plagued it for years. This article doesn't focus on solutions. It focuses on the rot at the foundation, the systemic trade-offs that make DeFi vulnerable, exploitable, and often unusable for the very people it's meant to empower. If you're looking for our solutions to some of these problems, read our article on [Silhouette's mission and vision for DeFi](https://docs.silhouette.exchange/blog/redefiningdefi.md). ## The Good: DeFi Has Product-Market Fit[​](#the-good-defi-has-product-market-fit "Direct link to The Good: DeFi Has Product-Market Fit") DeFi *works*. It’s global. It’s composable. And it’s accessible in a way that TradFi never could be. In markets where traditional infrastructure is broken, DeFi fills the gap with programmable money and uncensorable access. Millions have onboarded. A new generation of financial tools have emerged. But the question is no longer “does it work?” It’s “who is it working for?” ## The Bad: It’s Still Broken for Most Users[​](#the-bad-its-still-broken-for-most-users "Direct link to The Bad: It’s Still Broken for Most Users") Exploits. Bridge hacks. Rug pulls. Phishing. It’s hard to trust an industry where losing your life savings is one misclick away. But worse than the risk is the UX. DeFi is still alien to most users. Interfaces are clunky. Transaction flows are unintuitive. There are no safety nets. For most, it’s easier and safer to stay on a centralised exchange (CEX). And even for power users, there’s a deeper problem that undermines the entire structure: everything you do is public. ## Transparency: The Feature That Became a Flaw[​](#transparency-the-feature-that-became-a-flaw "Direct link to Transparency: The Feature That Became a Flaw") DeFi, up until now, has worshipped transparency. It’s what makes protocols verifiable and trustless. But in practice, it creates an information imbalance - a market structure where the most aggressive, technical actors feast on everyone else. Every transaction reveals intent. Every wallet exposes a portfolio. Every action is a signal. And for those watching, there’s money to be made. This isn’t theoretical. In 2024 alone, over [$968M was extracted](https://www.eigenphi.io/) via MEV. That’s not a fringe issue, that’s systemic leakage. Value drained before a trade executes, simply because it was broadcasted in the open. And MEV is just the start: * **Copy trading** scrapes public addresses to replicate positions. * **Sniping bots** wait for high-leverage liquidations. * **Quote fading** exploits slippage after seeing your size. In other words, DeFi gives everyone a Bloomberg terminal, but forces you to shout your trades into it. The surface-level story says DeFi is fair because it’s transparent. But fairness isn’t about openness, but rather about equal footing. Right now, most users operate blind while adversaries have a real-time edge. Builders are chased by forked clones. Traders are chased by bots. Institutions are chased away entirely. This isn’t just bad UX, it's a broken market structure. ## The Hyperliquid Exception?[​](#the-hyperliquid-exception "Direct link to The Hyperliquid Exception?") To be fair, some platforms are raising the bar. [Hyperliquid](https://hyperfoundation.org/) has proven that onchain doesn’t have to mean slow, illiquid, or clunky. It clears over $60B in weekly volume, with over [60% market share](https://dune.com/uwusanauwu/perps) among perps DEXs. And it does it all with native support for composability. But even here, the transparency issue persists. Better performance doesn’t remove the fact that order flow is exposed. Your strategy is still public. And alpha still leaks. Imagine a president announcing his every move before a public event. The route, the motorcade and the security detail. This isn’t transparent, it's a security risk. In DeFi, traders do the same thing unwillingly. The moment you sign a transaction, your intent becomes public. Price, size, direction - everything visible before it executes. That’s not fair, and it’s not secure. And it’s not how serious markets operate. ## What This Series Is Really About[​](#what-this-series-is-really-about "Direct link to What This Series Is Really About") This isn’t about dismissing DeFi. It’s about surfacing the contradictions we’ve buried under buzzwords. The next article in this series will look at the failed privacy experiments that came before and why they couldn’t scale. For now, just remember: in DeFi, transparency is a double-edged sword. And right now, it’s cutting the wrong side. ### Join Us Follow our journey and stay informed. * [](https://x.com/silhouette_ex) * [](https://silhouette.exchange/) * [](https://docs.silhouette.exchange/blog.md) * [](https://t.me/silhouette_exchange) --- # The Privacy Mirage - Why Complete Darkness Breaks DeFi July 14, 2025 · 3 min read [![Silhouette Team](/img/silhouette-team-avatar.png)](https://silhouette.exchange) [Silhouette Team](https://silhouette.exchange) Building the future of private trading ![The Privacy Mirage series header contrasting full darkness with shielded trading](/assets/images/problemwithprivacy-58e44abbcefbfb7aa061ffa7b318d657.png) *Part two of our three-part look at shielded trading.* Last week we argued that radical transparency turns DeFi into open season for front-running and strategy degradation. This follow-on asks a tougher question: what happens when we swing the pendulum the other way and hide everything? Short answer: hiding everything often hurts more than it helps. Trading into complete darkness is scary. ## Early privacy implementations and their shortcomings[​](#early-privacy-implementations-and-their-shortcomings "Direct link to Early privacy implementations and their shortcomings") ### Mixers[​](#mixers "Direct link to Mixers") Tornado Cash proved you can break the wallet-to-wallet link. It also proved regulators can break your liquidity. After OFAC’s August 2022 sanction, volume through the mixer fell by roughly 85 percent, sliding from $2.8 billion in the six months before the ban to [$425 million a year later](https://www.trmlabs.com/resources/blog/tornado-cash-volume-dramatically-reduced-post-sanctions-but-illicit-actors-are-still-using-the-mixer).  Privacy survived, users did not. ### Privacy L1s[​](#privacy-l1s "Direct link to Privacy L1s") Blockchains like Monero and Zcash protect every output, yet liquidity lives where traders meet. When OKX announced it would delist major privacy pairs on **5 January 2024**, [daily volumes and prices slipped across the sector](https://blockworks.co/news/crypto-exchanges-delisting-privacy-coins). A private rail with no major on-ramps becomes a dead end. ### Early Dark Pool DEXs[​](#early-dark-pool-dexs "Direct link to Early Dark Pool DEXs") Teams built fully encrypted swaps to keep order flow dark. They pushed the science forward, but market depth stayed shallow: * Penumbra’s TVL hovers near [$12k](https://defillama.com/protocol/penumbra-dex?dexVolume=true\&events=false\&tvl=false) and clears low-hundreds in daily volume. * Renegade’s TVL is around [$210k](https://defillama.com/protocol/renegade), with negligible volumes. * SecretSwap secures about [$480k](https://defillama.com/protocol/secretswap?denomination=USD). These numbers expose the network-effect cliff, not the quality of the code. Big pools attract bigger pools, which hide the signals “Makers” use to hedge.The result is that they will either quote a wide spread or walk away. Users on aggregate follow the tightest spread, so flow migrates back to transparent giants. ## UX and compliance friction[​](#ux-and-compliance-friction "Direct link to UX and compliance friction") Shielded rails promise safety, but they slow you down. First you deposit, then you wait for an anonymity set, pay proof gas, and bridge or wrap. In a market that clears in seconds, each extra click feels like a tax. Couple this with regulation and you have unnecessary weight. By using a sanctioned mixer means every compliance desk will freeze your address. The result of this means that big capital that could tighten spreads will steer clear, leading to no meaningful depth ever forming. Even when the tech hides your address, the timing and size of any trade will still leave a trail. If a grad student can trace it, a sniper bot can too. This meant that teams chased perfect secrecy end-to-end and, in the process, traded away a product people can use. ## The takeaway[​](#the-takeaway "Direct link to The takeaway") Version-one privacy tools hid everything. In doing so they stripped out the information that markets need to function, swapping alpha (strategy) leakage for a liquidity drought. Markets do not need to see your plan before the trade gets filled. They do need to see the trade’s fill after it lands and is settled. That insight shapes what comes next. ## Up next[​](#up-next "Direct link to Up next") Part three tests the hypothesis: keep intent secret, keep execution public. Trusted hardware makes that split possible. Same open ledger, zero alpha leak. Stay tuned. ### Join Us Follow our journey and stay informed. * [](https://x.com/silhouette_ex) * [](https://silhouette.exchange/) * [](https://docs.silhouette.exchange/blog.md) * [](https://t.me/silhouette_exchange) --- # Redefining DeFi with Silhouette June 10, 2025 · 4 min read [![Silhouette Team](/img/silhouette-team-avatar.png)](https://silhouette.exchange) [Silhouette Team](https://silhouette.exchange) Building the future of private trading ![Silhouette seed round announcement banner with RockawayX, Amber Group and HiveMind logos](/assets/images/raise-announcement-banner-5dd0c6f6169300bad745f0f12a6f4134.png) Decentralised Finance has come a long way since the DeFi Summer of 2020. What began as a movement for open, permissionless transactions has now matured into a high-speed, scalable ecosystem. But it is all out in the open – every move is completely visible to anyone watching. At Silhouette, we believe individual confidentiality enhances the foundational benefits of DeFi: accessibility and openness. The latest developments in cryptography enable us to apply verification to outcomes at a speed that matches the current on-chain pace. A transition from full transparency to verification is crucial to the future of an on-chain financial ecosystem. The DeFi economy will combine open financial markets with the natural desire for users to reduce the visibility of their positions within the market. Silhouette is based on the premise that open public markets and private user interactions are non-negotiable requirements to usher in an on-chain environment that fits the needs of all of finance. ## Introducing: The Shield Exchange[​](#introducing-the-shield-exchange "Direct link to Introducing: The Shield Exchange") Silhouette shields your Hyperliquid trades from prying eyes, allowing you to move freely and express your ideas in absolute confidence. We use Trusted Execution Environments (TEE) to provide order flow matching and settlement on Hyperliquid. TEEs enable us to offer a sense of speed and scale while also providing assurances that no one can view or tamper with your orders. ![Diagram of the Silhouette TEE-based order flow: encrypted orders route through a Trusted Execution Environment that settles against the public Hyperliquid orderbook](/assets/images/diagram-ac51541e7e18efc91f603e82efccf8cd.png) By offering users the choice to protect strategic trade information, we enable a sense of freedom in an ever-increasing industrial bot ecosystem looking to extract every ounce of value. If information is freely available, it will be exploited. Silhouette ensures that your actions, from placing orders to developing your overall strategy, remain protected. A key benefit of our system is the seamless ability to trade on HyperCore and HyperEVM. Apps, users, and builder code front-ends can utilise Silhouette to make interacting with Hyperliquid’s order book as simple as possible. We see simpler interfaces benefitting swaps, liquidations, the RFQ mechanism, TWAPs, and VWAPs. We are also excited about the potential of HIP-3, stablecoins and other features we have been working on, which we will share in the coming months. ## Our thesis[​](#our-thesis "Direct link to Our thesis") In finance, information asymmetry dramatically alters outcomes. When all participants possess the same information, markets tend towards efficiency, with prices reflecting intrinsic values. Strategies change as information sets shift; if any information is known, then it can be used in a different competing strategy. Strategic decision-making in finance is heavily dependent on the availability and distribution of information, which directly influences outcomes and market dynamics. Disclosure and reporting standards are examples of ensuring that as much information is on the same level for all users to attain. However, each user has a set of views and preferences, and their trades are an expression of that. In DeFi, users have limited tools to keep their preferences and views private while holding a market position. It is also well established that individual behaviours change when a person knows they are being watched. Maintaining the public availability of the overall market state while concurrently concealing individual user positions strikes an effective balance between market transparency and user privacy, which we view as the key differentiator for more financial use cases. This approach upholds market integrity and fairness by retaining public market knowledge while also granting users a degree of protection, empowering them to engage without risk of having their strategies compromised. ## Backed by the best, who share our vision[​](#backed-by-the-best-who-share-our-vision "Direct link to Backed by the best, who share our vision") Our industry fixed the speed and scale problem; Silhouette solves the privacy problem. The vision of Silhouette is to be the catalyst for the rest of the finance to come on-chain. Enabling users to express their views freely, in open and permissionless markets. ![Silhouette seed round investor lineup banner featuring RockawayX, Amber Group, HiveMind, No Limit Holdings and Protagonist](/assets/images/raise-banner-d2b4f74a667b893b8785c4b3a6a6e842.png) Silhouette is backed by a $3 million pre-seed round led by [RockawayX](https://www.rockawayx.com/), which includes investors such as [Amber Group](https://www.ambergroup.io/), [HiveMind](https://www.hivemind.capital/), [No Limit Holdings](https://nolimitholdings.xyz/), and [Protagonist](https://www.protagonist.co/). We are also extremely thankful for our angels from HyperActive. ### Join Us Follow our journey and stay informed. * [](https://x.com/silhouette_ex) * [](https://silhouette.exchange/) * [](https://docs.silhouette.exchange/blog.md) * [](https://t.me/silhouette_exchange) --- # Shielded Spot Trading - Live on Hyperliquid February 4, 2026 · 4 min read [![Silhouette Team](/img/silhouette-team-avatar.png)](https://silhouette.exchange) [Silhouette Team](https://silhouette.exchange) Building the future of private trading ![Cyberpunk illustration of a trader at a multi-monitor terminal executing shielded orders on Hyperliquid while a crowd watches in the background](/assets/images/shieldedspot-a5cd04f285becd878f4f3398230a5815.png) Over the last few months, we’ve been working with a series of traders and users refining the shielded experience. Today, we go live in an open beta. ## What Is Available[​](#what-is-available "Direct link to What Is Available") Spot HYPE/USDC using our shielded feature. The feature is accessible via our Silhouette App and API. Via the App, you can trade: * **Naked**: Works exactly as it does on Hyperliquid or any Builder Code frontend. * **Shielded**: Using the Silhouette environment and a delegated wallet to execute trades on the user’s instruction. ## How It Works[​](#how-it-works "Direct link to How It Works") Silhouette's trading mechanism starts with users depositing funds into a contract. This wallet processes and executes trades based on instructions from the Silhouette TEE (Trusted Execution Environment), which the user initiates. **User funds remain under user control**. They can only be managed via the user's original wallet. The Silhouette system can only process orders originating from the user's wallet and has no direct control over the user's funds without explicit instructions. Trades are executed directly on the Hyperliquid orderbook using the Silhouette system. Once a trade is completed, user balances are encrypted within a smart contract. This smart contract will be essential for our upcoming Sovereign Withdrawal feature, which ensures access to funds even if the Silhouette system is unavailable. ![Architecture diagram of the Silhouette shielded trading system: user wallet delegates to a TEE-attested execution module that places orders on Hyperliquid and encrypts balances inside a smart contract](/assets/images/shieldedtradingdiagram-9fb65e4f95c532560e0d241d1178538c.png) Silhouette supports policy engines as part of our plan to introduce compliance into our system. While we strongly advocate for open finance principles, we also recognise the need to make crypto markets more accessible to traditional financial participants. This is a nuanced and technical topic which deserves its own deep dive. If you represent a fund or any institutional entity interested in utilising this feature from its launch, please contact us through our public Telegram group to arrange access. ## Why This is Beneficial[​](#why-this-is-beneficial "Direct link to Why This is Beneficial") The system is the first step toward a fully fledged execution engine that can directly integrate with Hyperliquid order books. The current version enables a series of use cases: * User trades are shielded by the wallet's total trading volume, with higher volume making individual activity harder to isolate. * Silhouette wallets will soon get lower fees. We are working with partners to make Silhouette the cheapest venue to buy HYPE. More on this soon * The TEE is a conduit for users' intents on Hyperliquid while always maintaining funds are controlled by the users. With the above in mind, soon HIP-3 deployers, Spot buyers and [Spot Equities](https://x.com/WaynesWorldza/status/2016110304858427619?s=20) buyers will be able to discretely accumulate the required HYPE and other spot assets at the best possible price anywhere. This will be complimented with customisable policy engines for all your compliance needs. ## What's Next[​](#whats-next "Direct link to What's Next") This is just the first phase. Here is what to expect next: * More pairs rolled out to the shielded feature. Community requests are welcome. * HIP-3 markets support on the naked perps side. * Shielded TWAP and VWAP order types as part of our iceberg suite. * Request for Quote (RFQ) and Request for Match (RFM) infrastructure for larger workflows introduced. We’re looking for early users and market makers to test and shape this design. If that’s you, please reach out. * Net Settlement layer for reduced price impact by furthering our shielded offering. * While supported on day one of our launch, we will share more details on our policy engines and how they enable more use cases on-chain. * Future releases will introduce deeper intent protection, more expressive order types, and fully confidential routing that still settles in public. ![Silhouette Q1 roadmap graphic listing HIP-3 perps support, shielded TWAP and VWAP iceberg orders, RFQ and RFM infrastructure, and net settlement layer](/assets/images/q1-roadmap-472a08b8bcf3692f82b07b2ba561dcc0.png) Trade now: Want programmatic access? Reach out via our Telegram Community Channel. --- # Tokenised Stocks Won’t Trade Where You Think August 20, 2026 · 21 min read [Chandler](https://x.com/chandlerdkk) Co-Founder, Silhouette ![Tokenised Stocks Won’t Trade Where You Think series header with a wireframe liquidity surface rendered over the Silhouette monogram](/assets/images/tokenised-stocks-header-ad5759bdb874c2fa00cef73ce05a453a.png) Upfront disclosure: I can’t claim to be a neutral observer here. I’ll leave it at that for now, and you’ll see why by the end. Crypto finally has an honest map of its own market structure. Timon drew it [a few weeks back](https://x.com/0xtimon/status/2077676931127078950) in the best market-structure piece this industry has produced in a while, and the shape of it holds: no single onchain trading design wins. Liquidity flowed to propAMMs and RFQ because that’s where professional market makers set the price, while the long tail stayed with plain AMMs. Batch auctions are still waiting for the patient size they were built for, and the biggest capture happens one layer up, in the routers and wallets that own the users. The point that stayed with me came at the end: nobody can measure what any of this execution costs, because the people holding the data earn more by keeping it dark. I think the map is right. But a map only shows the territory that’s been settled, and this one ends at the edge of the flow that already lives onchain. Everyone in this industry claims a different kind of flow is on its way: issuer flow, meaning tokenised equities, funds, treasuries, and the institutions that want to trade them. That flow appears nowhere on the map, and it can’t use most of the venues. So when you ask where flow like that trades in traditional markets today, you get an answer that would bother anyone who assumes the order book is the endgame, because it mostly doesn’t trade on exchanges. ## The Blank Region on the Map[​](#the-blank-region-on-the-map "Direct link to The Blank Region on the Map") The map sorts every venue design by two questions: who sets your price, and how fresh it is. Every design on it competes for flow that’s already here: retail swaps, arbitrage, whales rotating majors. Issuer flow is different, and it’s different in three ways that matter. First, it starts from zero: a newly tokenised stock has no incumbent liquidity and no onchain price history, so no market maker has a reason to rest capital in it before demand exists. Second, it arrives with rules attached. A tokenised equity is not a meme coin with a ticker that happens to say TSLA. Depending on the issuer, it’s a bearer-style wrapper you can hold without identification, a token whose dividends and redemption rights activate only in a verified wallet, or a fully registered security where transfers to non-whitelisted addresses revert. Those rules come from the issuer’s regulator and charter, not from the venue, and they are not always optional. Third, the natural counterparties who trade in size are allergic to being seen doing it. Now look at the numbers. Tokenised equities held roughly $2.4bn in onchain value as of mid-August 2026, per [rwa.xyz](https://rwa.xyz). Solana carries over 95% of onchain tokenised-stock volume and cleared about $5.8bn of it in the second quarter of 2026 alone, which is less than QQQ trades before lunch on an average Tuesday. xStocks, meanwhile, has done more than [$35bn in total volume by its own count](https://x.com/xStocksFi/status/2087122040511668396). But the bulk of it matched on Kraken and Bybit’s centralised order books rather than onchain. The assets and the listings exist; the onchain market mostly doesn’t. Spreads are wide, books are thin, and the whole structure leans on a handful of market makers whose arbitrage maintains the peg. That isn’t quite a market yet, more inventory with a price feed. ![Tokenised stocks dashboard showing roughly $2.4bn of distributed onchain value alongside a chart of its growth over time](/assets/images/tokenised-stocks-rwa-value-caeb6f318fd8bc196498fab28ba31cb1.png) *Tokenized Stocks: distributed value \~2.4B plus the growth chart. Source: [app.rwa.xyz/stocks](https://app.rwa.xyz/stocks)* The standard response is patience: liquidity begets liquidity; give it time. Maybe. But there’s a better guide available. Traditional finance has been trading exactly this kind of instrument for decades: thin, rule-bound, traded in size. It settled on an answer, and the answer wasn’t an order book. ## What TradFi Does With This Flow[​](#what-tradfi-does-with-this-flow "Direct link to What TradFi Does With This Flow") Three data points carry this section, all of them boring, all of them important. 1. Start with US equities, where the [off-exchange share crossed 50% of volume](https://www.cboe.com/insights/posts/2025-u-s-equities-year-in-review) in early 2025 and has stayed around half since, split between dark pools, internalisers, and blocks negotiated upstairs and printed to the tape. The most liquid equity market on earth conducts half its business away from the lit book. 2. European ETFs are the closest thing TradFi has to a tokenised wrapper; a fund share’s depth lives in the primary market, not the secondary book. How they trade settles the question. Bloomberg and Tradeweb, two RFQ platforms, carry [about 57% of trading in the main European listings](https://www.etfstream.com/articles/bloomberg-and-tradeweb-rfq-platforms-dominate-european-etf-trading) between them, while the lit exchanges carry around 22%. Institutions ask a set of dealers for a price on their exact trade and take the best answer; the order book is the minority venue. 3. Then there are corporate bonds, hundreds of thousands of instruments, most of which don’t trade on a given day. [Over 60% of credit volume on MarketAxess](https://investor.marketaxess.com/) executes via disclosed RFQ, and electronic trading in US investment grade is approaching half the market. Nobody runs the long tail of CUSIPs on a central book, because there are too many instruments and not enough continuous interest in each one. The pattern generalises, and the economics explain why. Resting a quote on a thin instrument is a standing offer to be picked off by anyone better informed; that’s adverse selection, and it’s why passive AMM LPs bleed to arbitrage. A dealer answering an RFQ prices your specific trade, at your specific size, right now, and can decline flow that seems toxic. If an order book is a broadcast, an RFQ is a phone call. When instruments are many, trading is episodic, and size is sensitive, the phone call wins. There’s a second, less appreciated piece: TradFi doesn’t launch instruments into order books either. New ETFs get lead market makers with obligations, new listings get designated market makers, and new bond issues get allocated by dealers who then make the secondary market. The lit book is where instruments graduate once two-sided interest exists. ## Demand Discovery Comes Before Price Discovery[​](#demand-discovery-comes-before-price-discovery "Direct link to Demand Discovery Comes Before Price Discovery") This is the frame I keep coming back to, and it’s why I don’t read RFQ and order books as competitors. An order book does price discovery, and does it brilliantly, when continuous two-sided flow already exists. Hyperliquid is the proof: the [deepest book onchain by a wide margin](https://defillama.com/perps), around $6bn a day and the largest share of open interest, spreads on the crypto majors that embarrass most centralised venues. On liquid instruments, the book wins; the data says so, and I have no quarrel with it. ![DefiLlama perpetuals leaderboard with Hyperliquid ranked first at $11.7bn open interest and $6.2bn of 24-hour volume, well clear of Lighter, Variational and Aster](/assets/images/tokenised-stocks-perps-oi-d300b8f83fd88034852b7ecfa3d5ebc6.png) *Perps: Hyperliquid #1 by open interest (\~11.7B), about 6x its nearest rival. Source: [defillama.com/perps](https://defillama.com/perps)* Now put yourself in the issuer’s chair. Backed’s xStocks catalogue [crossed 700 tokenised assets](https://x.com/xStocksFi/status/2087881191756042653) in August, from 60 a year ago, and Dinari lists tokenised equities as an SEC-registered transfer agent. Say you want all of them tradable onchain. Launching hundreds of order books means funding the needed depth in each one before you know which tickers anyone wants. That’s an expensive way to learn that onchain demand for your 400th ticker is zero, and the failed books are public: a dead order book is negative marketing that updates in real time. RFQs invert this cost structure. Market makers rest nothing; they quote on request from inventory they already had access to, and one maker can cover many tickers that way because a quote costs nothing until someone asks for it. An issuer’s entire catalogue becomes quotable on day one, and every request is a demand signal for a specific ticker at a specific size for its underlying. The tickers that light up deservedly graduate to an order book carrying proven volume, and the makers who’ve been quoting them already know the flow. The book gets a listing that arrives with demand attached instead of a cold start. Demand discovery first, price discovery second. TradFi runs this sequence so routinely nobody names it; onchain has mostly been running it backwards. This August it finally ran forwards, and you could watch it happen. xStocks [arrived on Hyperliquid](https://x.com/xStocksFi/status/2086987212390875530) with native spot books on HyperCore, and it brought five tickers, not seven hundred: NVDAx, SPYx, QQQx, SKHYx and MUx, the names its centralised tape had already proven. That tape exists because an exchange like Kraken can pay the discovery bill for the head of its catalogue, cross-subsidising the market making from everything else it runs; nobody pays that bill seven hundred times, on either kind of rail. Volume did what young books do when the demand is already there, [$200k a day became $500k became $1m](https://x.com/mattdotfi/status/2090119436917162406) inside the first ten days, and MUx and SKHYx now sit among the venue’s most traded spot assets. The team’s own framing is the tell: they call the spot listings [complementary to HIP-3 perps](https://x.com/mattdotfi/status/2087202616572809647), the leg that lets traders run basis and delta-neutral strategies against the futures. xStocks ran demand discovery on centralised rails, sent five graduates to the book, and the rest of the catalogue still waits for a venue that can quote it on request without funding a single resting order. ## The Rulebook Problem[​](#the-rulebook-problem "Direct link to The Rulebook Problem") Cold starts are only half the issuer’s problem. The other half is that every issuer carries a different rulebook, and current onchain venues can’t read any of them. The spectrum I described above, from bare wrapper through rights-if-verified to name-in-register, is a real product decision that every issuer has already made differently. The issuers themselves can’t agree on the canonical wrapper, and the smart ones have stopped trying: nobody knows which point on that spectrum users want, so maybe we should stop arguing about it and let the market say what it wants? Okay, let the market decide, but none of the existing venue designs can serve that spectrum. An AMM pool can’t check anyone’s papers. Neither can a permissionless order book (and it shouldn’t, by the way); permissionlessness is its whole virtue. But that leaves issuer assets with a bad menu: trade the stripped-down bearer version everywhere, or trade the full-rights version almost nowhere. RFQ dissolves the problem almost by accident, because RFQ participation is permissioned by nature. Makers are onboarded, takers request, and the venue sits in the middle of every trade anyway so that it can ask one more question before settlement: does this wallet satisfy the issuer’s policy for this asset? Not the venue’s policy, the issuer’s. The plumbing for that question already runs in production today: programmable policy checks that execute before a transaction settles, with the verdict attested and enforced at the contract level. Institutions are already trading behind exactly this kind of gate. The design that matters is the neutrality. The issuer defines the policy, the trader carries their own credentials, since a KYC done once with the issuer travels with the wallet, and the venue holds everyone to the rules they each brought. The policy engine takes no side; it never touches a document, it just reads a yes or a no. Whether institutions show up for this is the honest open question; the industry has promised patient flow to new venue designs before and watched it not arrive. What I can say is that the stated blocker, “we can’t trade where we can’t enforce our obligations,” is an engineering problem now, not a structural one. ## What the Venue Would Have to Be[​](#what-the-venue-would-have-to-be "Direct link to What the Venue Would Have to Be") So let’s picture the venue this flow needs, and let me be clear: it’s not a thought experiment anymore; every piece I’m about to describe already exists in production somewhere. Let me be concrete enough to be falsifiable, because the design was never the hard part. It would run as one RFQ system on Hyperliquid, with the chains (HyperCore & HyperEVM) abstracted away so the trader sees none of the seams. The choice is reasoned, not tribal: the deepest onchain book, the HIP-3 long tail this design serves, and atomic settlement already live there. The interesting surface is the issuer one. Wire the request straight into the issuer’s mint and redeem functions, and when a taker asks for size, competing makers can quote from primary capacity as well as inventory, minting or redeeming with the issuer inside the settlement. Tradable depth becomes whatever the issuer can create, rather than whatever happens to be sitting in a pool. That authorised-participant structure makes TradFi assets onchain liquid, rebuilt as an atomic transaction. Spot would settle the same way, atomically against funded balances. Perps, including HIP-3 markets, deserve their own section below. The parts a finance reader judges would sit underneath the pitch. The taker’s request opens an auction window measured in seconds, makers respond with competing quotes carrying their own short expiries, and they update as the market moves. A quote like that ages in seconds, not minutes, because it never rests. Takers never see which maker is quoting them, so dealers compete without leaking their book. Makers keep a last look, but the counterweight is structural: a failed delivery fails the trade and the taker’s margin comes back untouched, never left eating a phantom fill. Now run it back through the two questions that decide any venue: who sets your price and how fresh is it. Here, competing professional dealers set the price, trade by trade. It’s seconds old too because it’s quoted on demand. Both boxes ticked. The fee you can’t see, the one the router layer below puts numbers on, becomes a single all-in quote here: a bill you can read before you accept it. ## Why RFQ Next to the Best Book Onchain[​](#why-rfq-next-to-the-best-book-onchain "Direct link to Why RFQ Next to the Best Book Onchain") The obvious objection is that Hyperliquid already has the deepest book in DeFi, so why do you need a dealer market next to it? For BTC and ETH perps at retail size, nobody; I said as much above. But the third property I flagged at the top, size that hates being seen, is not unique to issuer assets. Those are spot, the tokenised share itself. The same problem shows up in a different instrument, the perpetual, where you trade the price of the underlying rather than the share. HIP-3 made this concrete. Since builder-deployed markets went live in October 2025, anyone staking 500k HYPE can launch a perp market on equities, commodities, whatever an oracle can price. [Open interest across HIP-3 markets](https://hl.eco/hip-3) passed $4.2bn by mid-August 2026, and it now runs more than half of all Hyperliquid perp volume on a 30-day average, on its busiest days taking three-quarters of it. That’s a long tail of hundreds of markets with real open interest and thinner books than the crypto majors, which is what long tails look like. ![HIP-3 ecosystem dashboard showing total open interest and a bar chart comparing HIP-3 volume against crypto perps volume on Hyperliquid](/assets/images/tokenised-stocks-hip3-totals-51af6def1dd7927d2f6f73975d699969.png) *HIP-3: ecosystem totals and the HIP-3-vs-crypto-perps bar. Source: [hl.eco/hip-3](https://hl.eco/hip-3)* ![Table of the largest HIP-3 markets ranked by open interest, dominated by tokenised equities and commodities rather than crypto pairs](/assets/images/tokenised-stocks-hip3-markets-7a9a85cfa27de32a3a1127538c58d71c.png) *Top HIP-3 markets by open interest, tokenized equities and commodities, not crypto pairs. Source: [hl.eco/hip-3](https://hl.eco/hip-3)* By now the problem’s obvious: on a visible book, size is information the market front-runs into an expensive fill. Equities fixed this a long time ago by moving big trades off the public book: participants agree the block privately, then report it once it’s done. Matched execution is the onchain version of that private block trade. It delivers the block without a separate venue to hide in, using Hyperliquid’s own order book as the settlement rail instead of the thing you’re hiding from. You can’t open a HyperCore perp position except through the order book, so a venue built for this would choreograph the book rather than bypass it. A taker requests, a maker quotes, and on acceptance both pre-signed orders go into the Hyperliquid book at once, priced to cross against each other inside the spread. The taker’s margin commits when the request opens, and the maker’s margin is checked and simulated before anything touches the book. That’s what would make the fill close to deterministic rather than hopeful. Plain version: the two matching orders hit the book at the same instant, pre-priced to cross against each other unless the book can beat the price, so the trade is done before the market can react. As a taker, I’d want to know that the book can act as a price-improvement backstop. If the maker’s quote sits outside the current spread, the taker’s order fills against the book’s better prices first, and only the remainder crosses with the maker; anything left over is cancelled rather than left resting. You cannot do worse than the book you can see, and for size you avoid walking it. The position lands in each party’s own wallet; the venue custodies nothing. This is fundamentally different from what the spot-side RFQ is serving, but the goal is the same. The result is deliberately symbiotic: every RFQ perp fill prints as Hyperliquid volume, executed through the same book. The block trades without moving the market or announcing itself in advance and, by design, protects both parties. ## Back to the Routers[​](#back-to-the-routers "Direct link to Back to the Routers") The sharpest section of Timon’s piece was about the layer above all the venues: routers and wallets decide where orders go before any venue sees them, and some pricing sources game that decision. Publish an attractive quote to win the route simulation, reprice worse in the final slice of the block, and let the user’s own slippage tolerance eat the difference. His numbers put it at 3 to 10 basis points per trade, with the honest aggregators trapped displaying quotes that won’t settle, because blocking the cheaters makes your screen look worse. The structural fix for quote fade already exists: the firm quote. A signed, fixed-price, expiry-bound order cannot reprice in the last sliver of a block; the price you accepted either settles or the whole trade fails, and there is no slippage tolerance to eat because there is no slippage. So aggregators treat RFQ-style liquidity as first-class where they can get it: a signed quote gives their users a guaranteed price and immunity to sandwiching that no simulated route can promise. It also cuts the other way, which I suspect gets underrated. An RFQ venue doesn’t have to win the front-end war described above to reach takers, because it can export its quote surface outward to aggregators and wallets where the flow already lives, with the venue’s makers filling one hop behind. The venue that quotes firm prices travels well precisely because a router can trust it. In time, that’s the distribution story for issuer assets too: integrate once where the makers are, and become quotable wherever the routers reach. ## The Uncomfortable Question, From the Issuer Side[​](#the-uncomfortable-question-from-the-issuer-side "Direct link to The Uncomfortable Question, From the Issuer Side") Hanging over all of this is an uncomfortable question: if the endgame is professional market makers on fast rails, what have we actually built that TradFi doesn’t have? RFQ is decades old. Market making is older. For a trader swapping BTC, the question stings. For an issuer, the answer is concrete: getting a new security into TradFi’s dealer infrastructure takes a listing venue, a transfer agent, clearing membership, settlement plumbing, and a year of intermediaries, each taking a cut. Onchain, the trade settles whole or fails whole, custody stays with the holder, and it’s composable from day one. The rails are better. The venue design was the missing piece. ## Where Better Rails Pay Off: Margin[​](#where-better-rails-pay-off-margin "Direct link to Where Better Rails Pay Off: Margin") Better rails matter most where the old ones fail outright, and for issuer assets, that’s collateral. A listing on its own does nothing for an issuer; the utility everyone asks about first is margin, the ability to borrow against the token, run the basis trade, and post it as collateral. The demand is visible already, with xStocks landing on [Aave and Etherfi as collateral](https://x.com/xStocksFi/status/2088271522548809729) in the same August push that took it to Hyperliquid. But a lending market can only accept collateral it can liquidate, and a liquidation is just a block trade on a deadline, the worst possible order to work through a thin book. A liquidator who knows that won’t underwrite size, so the collateral never gets margined in the first place. An RFQ wired into the issuer’s mint and redeem changes that arithmetic, because the liquidation exit becomes the primary market itself, quoted on demand, in size, settling to stablecoin. Lending against tokenised equity stops being a bet on secondary depth. It becomes a claim on the issuer’s redemption capacity while the underlying market is open, which no lit book can offer, because no lit book can mint. And where an issuer’s rulebook requires verified liquidators, the same policy engine gates them like any other counterparty. Margin is where tokenised assets become interesting to hold; a dealer market with a redemption line is what makes them safe to lend against. ## The Scoreboard, Finally[​](#the-scoreboard-finally "Direct link to The Scoreboard, Finally") The missing scoreboard, the execution cost nobody can measure, is where this all lands, so let me close near it. An RFQ venue that settles on Hyperliquid would be the most measurable dealer market ever built. Every fill is public, and realised spread against any reference price is checkable by anyone with a block explorer, including people who dislike you. CoW Protocol got graded on its execution quality by outsiders only because its settlement data was open enough to allow it, and that cuts both ways: the transparent venue is the one that gets graded, and for anything courting institutions, that auditability is the product. Whoever builds this should expect to be graded on exactly this, and should welcome it. I’m not neutral about where this goes, which is exactly why I’d rather be graded on a public tape than believed. ## Where This Goes[​](#where-this-goes "Direct link to Where This Goes") I can see two futures from here. Future one: tokenised equities stay a rounding error onchain, institutions keep watching from the shore, and everything above is a well-argued answer to a question nobody asked. I can’t rule it out; the cold-start problem is real, and “traditional demand will simply arrive onchain” has been wrong before. In future two, demand stops waiting. It’s already visible everywhere it’s allowed to be: in the $35bn of tokenised-stock volume done mostly on centralised books, in the HIP-3 perps that now take more than half of Hyperliquid’s volume, and in five tokenised stocks doing their first $1m days on Hyperliquid spot. Give it onchain venues shaped like the flow, instead of venues the flow must be reshaped for, and I don’t think the first tokenised asset to do real size onchain will do it on a lit book. It will do it the way size has always traded, in every market that ever had any: on request, from a dealer, at a price quoted for that trade and no other. And then, with demand proven, it will graduate to the book. That’s the sequence TradFi has been running since before any of us were born. The only new part is that this time we have better settlement rails, and the venue shaped exactly like this flow is closer than you think. And the disclosure I owed you from the top: I’m not watching this one from the shore. We’ve already been building it. More on that soon. --- # Why Dark Pools Haven’t Worked Onchain August 12, 2025 · 5 min read [![Silhouette Team](/img/silhouette-team-avatar.png)](https://silhouette.exchange) [Silhouette Team](https://silhouette.exchange) Building the future of private trading ![Why Dark Pools Haven’t Worked Onchain series header with a fragmented liquidity visual](/assets/images/darkpoolsdontwork-edf9fc04032a7952324f24bbef90ebf2.png) *Part three in our series on shielded trading* Dark pools promised to fix DeFi’s biggest flaw: open exposure. For traders hunted by bots and shadowed by copycats, they offered something revolutionary, institutional-grade privacy. By hiding order flow, they aimed to level the playing field. And on paper, that made sense. But in practice, they became liquidity graveyards. The traders they were meant to serve stayed away. Makers refused to quote. Spreads widened. Volumes flatlined. So what went wrong? ## The Instinct Was Right: Transparency Hurts Traders[​](#the-instinct-was-right-transparency-hurts-traders "Direct link to The Instinct Was Right: Transparency Hurts Traders") As we explored in [Part One](https://mirror.xyz/0x5D2c2bD98F10616771D7B5124AD2090Ba72Aa43c/gFa2W0--Ref6ManqQ27m8drQAYqCNblOwjCeRJiYzZI), DeFi’s radical transparency exposes traders to all kinds of risk. When your order is visible before it executes, it becomes a target. MEV bots, copy traders, and snipers all thrive on this visibility. Naturally, the response was to go the other way. Hide everything. Encrypt every layer. Remove signals from the system. But this is where the pendulum swung too far. Dark pools didn’t fail because the problem was wrong. They failed because the solution was incomplete. As Jeff, founder of Hyperliquid, [put it](https://x.com/chameleon_jeff/status/1928883871644528890): > “Dark pools do not solve the main problems of crypto trading. Instead they throw out all the good parts of public blockchains and keep the bad.” Dark pools removed visibility without offering a better coordination mechanism. Traders need protection, but they also need liquidity. They need tight spreads, fast settlement, and the confidence that their counterparties will show up. In short, they need functioning markets. And functioning markets rely on more than secrecy. They rely on signal. Let’s look at what happened in practice: * **Penumbra**: \~$12,000 in TVL * **Renegade**: \~$210,000 in TVL * **SecretSwap**: \~$480,000 in TVL These were not poorly engineered products. In fact, they were serious attempts at solving a real problem. But the much-needed liquidity never came and volumes never picked up, preventing meaningful depth from ever forming. These dark pools created total privacy, but they also created total silence. Without visibility into the order book or intent, market makers could not hedge or quote effectively. Spreads widened, users left, and the feedback loop collapsed before it could start. Again, Jeff captured the [deeper issue](https://x.com/chameleon_jeff/status/1929753039969440212): > “The important thing is coordination… A successful crypto exchange is not about copying NYSE but rebuilding coordination with different primitives.” ## Breaking Down The Failure[​](#breaking-down-the-failure "Direct link to Breaking Down The Failure") There were three core reasons these systems failed to gain traction: ### 1. Too private, too early[​](#1-too-private-too-early "Direct link to 1. Too private, too early") Hiding everything stripped out the minimal information that market makers need to function. In traditional markets, even dark pools provide post-trade transparency and rely on a lit reference price to anchor quotes. DeFi dark pools often removed both. As a result, they attracted neither market makers nor users. ### 2. User experience friction[​](#2-user-experience-friction "Direct link to 2. User experience friction") Privacy was often bolted on in ways that made usage painful. To trade, users had to deposit funds, wait for an anonymity set to form, pay high proof-generation fees, and then bridge or wrap tokens. In a world where execution is measured in milliseconds, this kind of friction becomes a dealbreaker. ### 3. The liquidity spiral[​](#3-the-liquidity-spiral "Direct link to 3. The liquidity spiral") Tight spreads attract flow. Flow attracts more liquidity. But when spreads are wide and depth is thin, users abandon ship. Dark pools struggled to bootstrap this cycle because the starting conditions were too constrained. Privacy was prioritised at the cost of usability. ![Liquidity depth comparison chart showing thin onchain dark pool order books versus deep continuous liquidity on public venues](/assets/images/liquiditydifference-6327aa1295494830e40dc7cd9bc53cce.png) The end result? Empty pools, despite good intentions. ## What Markets Actually Need[​](#what-markets-actually-need "Direct link to What Markets Actually Need") Privacy is important. But it must be designed in service of the market, not at its expense. What markets need is a balance: * **Keep order intent private before execution** * **Make execution data public after the trade settles** This preserves strategic privacy while maintaining the visibility markets rely on to function. It allows traders to shield their [alpha](https://www.investopedia.com/terms/a/alpha.asp), while still anchoring coordination. Makers can still quote, takers can trust and liquidity can still be allowed to form. This is the backbone of every functional market. Even in TradFi, dark pools operate alongside visible reference prices and post-trade reporting. Coordination and trust do not come from hiding everything, but rather from shielding the right things. ## What Makes Silhouette Different[​](#what-makes-silhouette-different "Direct link to What Makes Silhouette Different") Silhouette is not just another dark pool. It is a shielded execution layer built on Hyperliquid – one of the fastest, deepest and most composable chains in DeFi. We do not hide everything. We shield intent. * Orders are encrypted inside secure hardware enclaves (TEEs) before execution * After execution, the fill price, volume, and timestamp are posted publicly * This preserves trader privacy without sacrificing coordination You can think of it like public transit. Everyone sees the timetable, but no one knows who sat in seat 12C. By protecting the strategy and exposing the outcome, Silhouette strikes the balance that previous designs missed. ## Learn, Adapt, Build[​](#learn-adapt-build "Direct link to Learn, Adapt, Build") The first generation of dark pools misunderstood what markets actually need. They focused on secrecy, but ignored coordination. They built cryptography, but forgot liquidity. Silhouette learns from those mistakes. We do not believe privacy and performance are in conflict. We believe they can coexist. But only if we treat markets as living systems, not puzzles to be solved in a vacuum. Privacy, alone, is not a product. But usable, composable, shielded trading? That is a new foundation. ### Join Us Follow our journey and stay informed. * [](https://x.com/silhouette_ex) * [](https://silhouette.exchange/) * [](https://docs.silhouette.exchange/blog.md) * [](https://t.me/silhouette_exchange) --- [Skip to main content](#__docusaurus_skipToContent_fallback) [Skip to main content](#__docusaurus_skipToContent_fallback) [![Silhouette Exchange](/img/silhouette-title-logo.svg)![Silhouette Exchange](/img/silhouette-title-logo.svg)](https://docs.silhouette.exchange/index.md) [**Silhouette**](https://docs.silhouette.exchange/index.md)[Docs](https://docs.silhouette.exchange/about-silhouette.md)[Blog](https://docs.silhouette.exchange/blog.md) [Launch App](https://app.silhouette.exchange) Search --- # Introduction ## What is Silhouette?[​](#what-is-silhouette "Direct link to What is Silhouette?") Silhouette is the universal block trading layer on Hyperliquid. One RFQ flow to trade size across the instruments on HyperCore and HyperEVM: tokenized stocks, spot pairs, and perps. An RFQ (request for quote) works differently from an order book. Instead of working an order on a public book, you ask market makers for firm prices on the exact size you want. Makers compete for your trade during a short quote window, the best quote wins, and the trade settles on-chain. The full amount fills at one price, and your intent stays shielded from the wider market while makers compete. ## Who it serves[​](#who-it-serves "Direct link to Who it serves") **Takers** request liquidity. Submit an RFQ for an instrument, review the competing quotes (or let the best one be accepted automatically), and track the trade to settlement. Funds can sit on HyperCore or HyperEVM; settlement returns them to the chain you started from. **Makers** provide liquidity. Watch for open RFQs on your approved instruments, submit quotes, and fill the trades you win. Quotes can settle from inventory, through an external venue, or as a bounded promised delivery, so competitive pricing does not require parking idle capital. Silhouette coordinates the flow between the two sides. Takers and makers never interact directly. ## Where to start[​](#where-to-start "Direct link to Where to start") * **Trading through the app**: [Quickstart for Takers](https://docs.silhouette.exchange/quickstart/takers.md) * **Making markets or integrating**: [Quickstart for Makers](https://docs.silhouette.exchange/quickstart/makers.md) and the [RFQ API](https://docs.silhouette.exchange/rfq/api.md) * **Understanding the flow end to end**: [How RFQs Work](https://docs.silhouette.exchange/rfq/overview.md) --- Identity system # The Silhouette *Brand* Logos, colour, typography, and voice for everything published under the Silhouette name. [Download all assets ↓](https://docs.silhouette.exchange/img/brand/silhouette-brand-assets.zip)[Jump to logos](#logos) ![](/img/brand/hero-s-gradient.svg) 01 / LOGOS · NODE.LOGO · SVG / PNG ## Three marks. One *System* Every mark ships in SVG and PNG, mono and colour, tuned for dark and light surfaces.
Toggle a variant to preview it, then download or copy the source directly. ![Silhouette Icon, icon white on transparent bg](/img/brand/logos/icon/svg/icon-white-on-transparent-bg.svg) ### Icon MARK / 01 The standalone glyph. App icons, avatars, favicons, and tight spaces. MonoColour On darkOn light [SVG ↓](https://docs.silhouette.exchange/img/brand/logos/icon/svg/icon-white-on-transparent-bg.svg)[PNG ↓](https://docs.silhouette.exchange/img/brand/logos/icon/png/icon-white-on-transparent-bg.png) ![Silhouette Wordmark, wordmark white transparent bg](/img/brand/logos/wordmark/svg/wordmark-white-transparent-bg.svg) ### Wordmark MARK / 02 Text only. Use where the icon already appears nearby, or in a strict single line. MonoColour On darkOn light [SVG ↓](https://docs.silhouette.exchange/img/brand/logos/wordmark/svg/wordmark-white-transparent-bg.svg)[PNG ↓](https://docs.silhouette.exchange/img/brand/logos/wordmark/png/wordmark-white-transparent-bg.png) ![Silhouette Icon + Wordmark, logo white on transparent bg](/img/brand/logos/icon+wordmark/svg/logo-white-on-transparent-bg.svg) ### Icon + Wordmark MARK / 03 The primary lockmark. The default for headers, decks, and other materials. MonoColour On darkOn light [SVG ↓](https://docs.silhouette.exchange/img/brand/logos/icon+wordmark/svg/logo-white-on-transparent-bg.svg)[PNG ↓](https://docs.silhouette.exchange/img/brand/logos/icon+wordmark/png/logo-white-on-transparent-bg.png) 02 / CLEAR SPACE · NODE.SPACE ## Give the mark *room*. ![](/img/brand/clear-space/corner-s-56.svg)![](/img/brand/clear-space/corner-s-56.svg)![Silhouette icon with clear space](/img/brand/clear-space/s-mark-112.svg)![](/img/brand/clear-space/corner-s-56.svg)![](/img/brand/clear-space/corner-s-56.svg) Clear space at lease half the icon size ![](/img/brand/clear-space/corner-s-72-left.svg)![](/img/brand/clear-space/corner-s-72-left.svg)![Silhouette wordmark with clear space](/img/brand/clear-space/wordmark-strip.svg)![](/img/brand/clear-space/corner-s-72-right.svg)![](/img/brand/clear-space/corner-s-72-right.svg) Clear space on all sides equals the height of the icon. Nothing, no text, edges, or other logos, enters that field. 02.5 / CLEAR SPACE · PARTNERSHIPS ![RockawayX and Silhouette partnership lockup with clear space](/img/brand/clear-space/partnerships.svg) The logos should be the same optical height. and sufficient space around both logos. 03 / MISUSE · NODE.GUARD ## Do not ![](/img/brand/logos/icon+wordmark/svg/logo-white-on-transparent-bg.svg) ✕ Don't recolour the mark ![](/img/brand/logos/icon+wordmark/svg/logo-white-on-transparent-bg.svg) ✕ Don't stretch or distort ![](/img/brand/logos/icon+wordmark/svg/logo-white-on-transparent-bg.svg) ✕ Don't rotate the mark ![](/img/brand/logos/icon+wordmark/svg/logo-white-on-transparent-bg.svg) ✕ Don't add shadows or glows ![](/img/brand/logos/icon+wordmark/svg/logo-white-on-transparent-bg.svg) ✕ Don't reduce contrast ![](/img/brand/logos/icon+wordmark/svg/logo-white-on-transparent-bg.svg) ✕ Don't rebuild in another font Aa 04 / TYPE · INTER ## Inter, the one and *only* One typeface carries everything: display, body, and chrome. Inter runs with the slashed zero always on. **Display**Inter 200 · -0.04em Size finds *size*. **Headline**Inter 300 · -0.025em Every market. Every instrument. **Title**Inter 300 · dim Execution at the scale and discretion finance requires. **Body**Inter 400 · 1.55 The coordination layer for liquidity to flow freely. A mechanism for coordinating optimal flow for size while neutralising the economic cost of revealing intent. **Label · chrome**Inter 500 · tracked caps BLOCK TRADING · HIP-4 · T+0.42 · SILHOUETTE.EXCHANGE **Numerals**Tabular · cv11 slashed zero 0123456789 · $100,000,000 · $0.62 05 / COLOUR · NODE.SIGNAL · 9 TOKENS ## Restraint, made *visible* A dark canvas, a tight cool-grey ramp, and two signal colours that carry meaning: pink and blue. PinkPink#fea6ffPre-matched block execution
carries pink.BlueBlue#94fff9The lit book, public and
observed, carries blue. Canvas#13161aDefault page canvas. Not pure black. Slightly cool.Panel#16181dCards, panels, inner surfaces.Line#23262dDividers, hairlines, frame rules, plate borders.Line 2#2d3138Heavier dividers, frame-corner brackets.Text mute#5a5f68Micro-labels, footer telemetry, dim metadata.Text dim#8a8f98Subtitles, supporting copy, nav at rest.Text#e8ebf0Default text. Never pure white. 06 / BOILERPLATE · NODE.COPY ## Approved copy Use these verbatim in press, listings, and partner materials. Do not paraphrase the description. One line Silhouette is the universal block trading layer on Hyperliquid. Every market. Every instrument. Copy text Standard Silhouette is the universal block trading layer on Hyperliquid. It lets the largest liquidity in the world move size at Hyperliquid's depth without moving the book. Quotes compete for every order, and settlement remains on HyperCore. Copy text 07 / DOWNLOADS · NODE.DIST ## Take it with you. ### Full asset pack Every logo, in SVG and PNG, mono and colour, across all background variants. [Download .zip ↓](https://docs.silhouette.exchange/img/brand/silhouette-brand-assets.zip) ### Brand guide The full guide as a PDF: logos, colour, type, and usage rules in one document. [Download .pdf ↓](https://docs.silhouette.exchange/img/brand/silhouette-brand-guide.pdf.zip) ### Copy for an LLM The whole kit as plain text: palette, type, rules, and voice. Paste into any model or brief. Copy brand as text ### Brand questions Partnerships, co-branding, or a use that is not covered here. Talk to the team first. [Contact ↗](mailto:team@silhouette.exchange) ![](/img/brand/footer-s.svg) Every market.
Every instrument. The universal *block trading layer*
for Hyperliquid --- # FAQs ### What is an RFQ?[​](#what-is-an-rfq "Direct link to What is an RFQ?") A request for quote. You ask market makers for firm, executable prices on the exact size you want to trade. Makers compete during a quote window, the best quote wins, and the trade settles on-chain at one price for the full amount. ### What can I trade?[​](#what-can-i-trade "Direct link to What can I trade?") Each RFQ is for one instrument, identified as `BASE-QUOTE-TYPE` (for example `TSLAX-USDC-SPOT`). The flow spans tokenized instruments on HyperEVM and spot and perp venues on HyperCore, and the supported set grows over time. See [How RFQs Work](https://docs.silhouette.exchange/rfq/overview.md#instruments). ### Do my funds need to be on HyperCore or HyperEVM?[​](#do-my-funds-need-to-be-on-hypercore-or-hyperevm "Direct link to Do my funds need to be on HyperCore or HyperEVM?") Either. Settlement abstracts the chain away and returns funds to the chain you initiated from. ### How is the winning quote chosen?[​](#how-is-the-winning-quote-chosen "Direct link to How is the winning quote chosen?") You choose the mode per RFQ. With auto-acceptance, the best conforming quote is accepted automatically when the quote window closes. With manual acceptance, you review the competing quotes and accept one yourself before the deadline. See [How RFQs Work](https://docs.silhouette.exchange/rfq/overview.md#auto-acceptance-two-round-flow). ### Can makers see my price limit?[​](#can-makers-see-my-price-limit "Direct link to Can makers see my price limit?") No. An optional price limit bounds which quotes can win, and it is never shown to makers. ### When do funds lock?[​](#when-do-funds-lock "Direct link to When do funds lock?") With auto-acceptance, at RFQ submission. With manual acceptance, when you accept a quote. If the RFQ is cancelled or settlement fails, locked funds are released. ### What are the fees?[​](#what-are-the-fees "Direct link to What are the fees?") 5 bps (0.05%) all-in on spot, 1.4 bps on perpetuals, published per instrument as `takerFeeTenthBp`. A spot fee is inside the quoted price; a perpetual's is charged at Hyperliquid on your own account. See [Fees](https://docs.silhouette.exchange/fees.md). ### Why did my RFQ get no quotes?[​](#why-did-my-rfq-get-no-quotes "Direct link to Why did my RFQ get no quotes?") A market can set a smallest order value it takes, published on the instrument as `minQuoteNotional`. A request under it is rejected outright with `BELOW_MIN_NOTIONAL` rather than left to expire, and the rejection names the figure to resize from — so if you got no quotes rather than a rejection, size was not the reason. Above the minimum, an RFQ can still end with no quotes if no maker priced it in the window; market hours matter for an instrument tied to an underlying session. See [Minimum order value](https://docs.silhouette.exchange/rfq/overview.md#minimum-order-value). ### Is there an API?[​](#is-there-an-api "Direct link to Is there an API?") Yes. REST for all mutations and WebSocket for live streams, sharing one authentication model. Start with the [RFQ API overview](https://docs.silhouette.exchange/rfq/api.md) or go straight to [your first trade](https://docs.silhouette.exchange/rfq/api/first-trade.md). ### How do I become a maker?[​](#how-do-i-become-a-maker "Direct link to How do I become a maker?") Makers quote the instruments they are approved for. Reach out on [Telegram](https://t.me/silhouette_exchange) to get onboarded, then follow the [Quickstart for Makers](https://docs.silhouette.exchange/quickstart/makers.md). --- # Fees *All fee rates are expressed in basis points (bps). 1 bp = 0.01%.* Every market publishes its own taker fee. Read it from `takerFeeTenthBp` on `GET /v1/rfq/instruments`, in tenths of a basis point, rather than assuming a single venue-wide rate. As of 3 October 2026 spot markets charge **5 bps (0.05%)** and perpetuals **1.4 bps (0.014%)**. Makers are not charged. ## Where the fee is taken[​](#where-the-fee-is-taken "Direct link to Where the fee is taken") On **spot**, the fee is inside the all-in price a quote shows you. `takerTotal` is what you pay, fee included, and `quoteLimit` bounds that same all-in figure — so a quote wins only if its `takerTotal` is at or under your limit. There is no separate fee line on the trade. On a `BUY` the fee is the market's rate applied to what the winning maker receives; on a `SELL`, to the `baseQty` you deliver. The rate is the one in force when you submitted, not when the quote arrived. On **perpetuals**, nothing is custodied and Silhouette moves no funds, so the fee cannot sit inside the quote. Hyperliquid charges it on your own account as a builder fee, at the same rate the instrument publishes. It is outside `takerTotal` and outside the RFQ's `takerFee`, and you approve the rate at the venue before requesting quotes. The fee schedule will evolve as the venue matures. --- # Glossary Terms used throughout Silhouette documentation. *** ### Auto-acceptance[​](#auto-acceptance "Direct link to Auto-acceptance") The two-round RFQ flow. The taker submits with `autoAccept: true` and the best conforming quote is accepted automatically when the quote window closes. Funds lock at submission. ### HyperCore[​](#hypercore "Direct link to HyperCore") The high-performance trading engine of Hyperliquid, purpose-built for financial primitives. ### HyperEVM[​](#hyperevm "Direct link to HyperEVM") The Ethereum Virtual Machine-compatible layer of Hyperliquid. Supports smart contracts and tokenized instruments. ### Instrument[​](#instrument "Direct link to Instrument") What a single RFQ trades, identified as `BASE-QUOTE-TYPE` (for example `TSLAX-USDC-SPOT`): the base token, the quote token, and the product type. ### Maker[​](#maker "Direct link to Maker") The market maker that prices an instrument and fills the trade. Makers watch for open RFQs on their approved instruments and submit competing quotes. ### Manual acceptance[​](#manual-acceptance "Direct link to Manual acceptance") The three-round RFQ flow. The taker reviews competing quotes and explicitly accepts one before the deadline. Funds lock at acceptance. ### Permit2[​](#permit2 "Direct link to Permit2") The on-chain authorization standard Silhouette uses to bind quote expiries to settlement deadlines. A selected quote carries an engine-signed Permit2 authorization the maker relays on-chain to settle. ### Promised delivery[​](#promised-delivery "Direct link to Promised delivery") A settlement mode where the maker owes the on-chain delivery within a bounded window after winning, rather than settling atomically from inventory. ### Quote window[​](#quote-window "Direct link to Quote window") The period during which makers can submit competing quotes for an open RFQ. A short window favors faster execution; a longer window gives more makers time to respond. ### RFQ (request for quote)[​](#rfq-request-for-quote "Direct link to RFQ (request for quote)") A trading workflow where a taker asks makers for executable prices on a specific instrument, receives competing quotes, and settles the winning quote on-chain. ### Settlement[​](#settlement "Direct link to Settlement") The final on-chain execution of a winning quote. Settlement abstracts the chain away: funds return to the chain the taker initiated from, whether HyperCore or HyperEVM. ### Taker[​](#taker "Direct link to Taker") The account requesting liquidity. A taker creates the RFQ, reviews quotes (or uses auto-acceptance), and tracks the trade to settlement. --- # Quickstart for Makers Makers price and fill RFQs through the [RFQ API](https://docs.silhouette.exchange/rfq/api.md). The flow below takes you from credentials to your first filled trade. ## 1. Get approved to quote[​](#1-get-approved-to-quote "Direct link to 1. Get approved to quote") Makers quote the instruments they are approved for. If you are not yet onboarded, reach out to the team on [Telegram](https://t.me/silhouette_exchange) to get set up. ## 2. Mint API credentials[​](#2-mint-api-credentials "Direct link to 2. Mint API credentials") Authentication is wallet-based: a SIWE login mints an access key and HMAC secret, and every private request is signed with the secret. Follow the [authentication guide](https://docs.silhouette.exchange/rfq/api.md#authentication). ## 3. Deposit funds[​](#3-deposit-funds "Direct link to 3. Deposit funds") Send funds on-chain; Silhouette observes and credits deposits to your account. Withdrawals are asynchronous and always return to your account's registered address, and may name the custody rail to pay from. Balances are reported per token and per custody rail, each line carrying available, locked, and pending amounts plus the ceiling on a single withdrawal from that rail, and the ledger gives you an append-only audit trail for reconciliation. See the balance and funding endpoints in the [API Reference](https://docs.silhouette.exchange/rfq/api/reference.md). ## 4. Discover and quote[​](#4-discover-and-quote "Direct link to 4. Discover and quote") Poll `listMakerRequests` for open RFQs on your approved instruments, or subscribe to the WebSocket streams for live updates. Submit quotes with `createMakerQuote`. A quote declares how it settles: from your inventory, through an external venue, or as a promised delivery within a bounded window. ## 5. Settle what you win[​](#5-settle-what-you-win "Direct link to 5. Settle what you win") At the deadline one quote is selected. Read your `SELECTED` quote back through `listMakerQuotes`; it carries the engine-signed Permit2 authorization you relay on-chain to settle. ## Next steps[​](#next-steps "Direct link to Next steps") * [Your first trade](https://docs.silhouette.exchange/rfq/api/first-trade.md) - the full request-to-settlement walkthrough with both API surfaces * [How RFQs Work](https://docs.silhouette.exchange/rfq/overview.md) - quote windows, selection, and lifecycle states * [Market making on xStocks](https://docs.silhouette.exchange/rfq/market-making/xstocks.md) - quoting and settling Backed's tokenized equities on HyperEVM * [Market making on HyperCore](https://docs.silhouette.exchange/rfq/market-making/hypercore.md) - quoting HyperCore spot pairs from inventory or by promised delivery, and perpetuals by matched execution --- # Quickstart for Takers Place your first RFQ in five steps. You will need an EVM wallet and funds on HyperCore or HyperEVM. ## 1. Connect your wallet[​](#1-connect-your-wallet "Direct link to 1. Connect your wallet") Go to [app.silhouette.exchange](https://app.silhouette.exchange) and click **Connect Wallet**. ## 2. Deposit funds[​](#2-deposit-funds "Direct link to 2. Deposit funds") Deposit the token you want to trade with. Your funds can sit on HyperCore or HyperEVM; settlement always returns funds to the chain you started from. ## 3. Request a quote[​](#3-request-a-quote "Direct link to 3. Request a quote") Choose an instrument, a side (buy or sell), and the amount you want to trade. Optionally set a price limit; a quote outside your limit can never win, and makers never see it. ## 4. Accept a quote[​](#4-accept-a-quote "Direct link to 4. Accept a quote") Makers compete for your trade during the quote window. You have two options: * **Auto-accept**: the best conforming quote is accepted for you when the window closes. * **Manual**: review the competing quotes and accept one yourself before the deadline. If no conforming quote arrives, the RFQ ends `FAILED` and any locked funds are released. Cancelling the request yourself, while it is still open, ends it `CANCELLED` instead. ## 5. Track the trade[​](#5-track-the-trade "Direct link to 5. Track the trade") Follow the trade to settlement in your activity view. A settled trade carries the on-chain settlement transaction. See [How RFQs Work](https://docs.silhouette.exchange/rfq/overview.md#trade-lifecycle) for every state a trade can pass through. ## Next steps[​](#next-steps "Direct link to Next steps") * [How RFQs Work](https://docs.silhouette.exchange/rfq/overview.md) - the full flow, quote windows, and lifecycle states * [RFQ API](https://docs.silhouette.exchange/rfq/api.md) - do all of the above programmatically --- # RFQ API The RFQ API gives programmatic access to request-for-quote trading on Silhouette: takers request quotes and accept them, makers price and fill them, and both sides manage balances, deposits, and withdrawals. It has two surfaces: * The [REST API](https://docs.silhouette.exchange/rfq/api/rest.md) for authentication, instruments, tokens, RFQs, quotes, balances, and funding. Every mutation goes over REST. * The [WebSocket API](https://docs.silhouette.exchange/rfq/api/websocket.md) for live RFQ, quote, balance, and price streams. Both share one authentication model, documented below. To see the whole flow end to end, follow [your first trade](https://docs.silhouette.exchange/rfq/api/first-trade.md). For a plain-language explanation of how RFQs work, see the [RFQ overview](https://docs.silhouette.exchange/rfq/overview.md). ## Base URL[​](#base-url "Direct link to Base URL") The production API host: ``` https://rfq-api.silhouette.exchange ``` REST endpoints live under `/v1`. The shared WebSocket client stream is `wss://rfq-api.silhouette.exchange/v1/rfq/ws`; makers publish price ladders to a separate maker-only socket at `/v1/rfq/prices/ws`. ## Specifications[​](#specifications "Direct link to Specifications") Both API surfaces are described by machine-readable specifications, which are the source for the interactive [API Reference](https://docs.silhouette.exchange/rfq/api/reference.md): | Surface | Format | Spec | Reference | | ------------------------------------------------------------------ | ------------ | ---------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | | [REST](https://docs.silhouette.exchange/rfq/api/rest.md) | OpenAPI 3.1 | [`/api/rfq-openapi.yaml`](https://docs.silhouette.exchange/assets/files/rfq-openapi-274f80955669a8308555ec1d652cd4f3.yaml) | [REST reference](https://docs.silhouette.exchange/rfq/api/reference.md) | | [WebSocket](https://docs.silhouette.exchange/rfq/api/websocket.md) | AsyncAPI 3.0 | [`/api/rfq-asyncapi.yaml`](https://docs.silhouette.exchange/assets/files/rfq-asyncapi-a9f26cf35c4a235cd9c3a3179e4f6b06.yaml) | [WebSocket reference](https://docs.silhouette.exchange/rfq/api/reference.md#websocket/description/introduction) | ## Authentication[​](#authentication "Direct link to Authentication") The RFQ API uses wallet-based SIWE login to mint API credentials, then HMAC signatures on every private request. Public market-data endpoints are unauthenticated. ### Login flow[​](#login-flow "Direct link to Login flow") 1. Request a single-use nonce with `POST /v1/auth/challenge`. 2. Build a SIWE (EIP-4361) message that includes the nonce, gateway domain, URI, chain ID, and issued-at timestamp. 3. Sign the SIWE message with the account wallet. 4. Submit the SIWE message and wallet signature to `POST /v1/auth/api-keys`. 5. Store the returned public `accessKey` and base64 `secret`. 6. Sign each private request with the HMAC secret. The secret is returned only once, at login, and never again. Treat it as a production secret and rotate it by minting a new key before revoking the old one. Keep the secret out of the browser. The interactive [API Reference](https://docs.silhouette.exchange/rfq/api/reference.md) sends public market-data requests only: login and the private operations are refused from that origin by design, since anything running on a page can read what you type into it. Sign requests from curl or your own client instead. Whitespace and line breaks are part of the SIWE payload, so sign exactly the message you send to the API: ``` {domain} wants you to sign in with your Ethereum account: {address} Create Silhouette API key URI: https://{domain}/ Version: 1 Chain ID: {chainId} Nonce: {nonce} Issued At: {issuedAt} ``` ### Signing requests[​](#signing-requests "Direct link to Signing requests") Every private request carries three headers: | Header | Value | | -------------------------- | ------------------------------ | | `Authorization` | `Bearer ` | | `Silhouette-API-Timestamp` | Unix timestamp in milliseconds | | `Silhouette-API-Signature` | Base64 HMAC-SHA256 signature | The signature is the HMAC-SHA256, under the secret, of the canonical string built from the exact request data the server receives: ``` {timestamp} {METHOD} {path}?{query} {body} ``` For `GET` and bodyless `DELETE` requests the body line is empty. For query-string endpoints, such as `DELETE /v1/auth/api-keys?all=true`, include the query string in the signed path. Requests are accepted only when the timestamp is fresh within the gateway window, currently 30 seconds. ``` import base64 import hashlib import hmac import time TIMESTAMP_HEADER = "Silhouette-API-Timestamp" SIGNATURE_HEADER = "Silhouette-API-Signature" def hmac_headers(access_key, secret_b64, method, path, body=""): secret = base64.b64decode(secret_b64) timestamp = str(int(time.time() * 1000)) message = "\n".join([timestamp, method.upper(), path, body]).encode() signature = base64.b64encode( hmac.new(secret, message, hashlib.sha256).digest() ).decode() return { "Authorization": f"Bearer {access_key}", TIMESTAMP_HEADER: timestamp, SIGNATURE_HEADER: signature, } ``` For `POST` requests, sign the serialised JSON string you send. If the body bytes differ from the bytes used to compute the signature, the gateway rejects the request. The shared WebSocket stream is authenticated the same way, in an in-band `auth` frame sent after connecting (the credential pair signs a canonical `GET /v1/rfq/ws`), because browsers cannot set headers on the WebSocket upgrade. The socket is authenticated once; later frames carry no signature. See the [WebSocket API](https://docs.silhouette.exchange/rfq/api/websocket.md) page for the frame protocol. ### Key lifecycle[​](#key-lifecycle "Direct link to Key lifecycle") Multiple live keys can belong to the same account at the same time, which allows gradual rotation: 1. Mint a new key. 2. Move traffic to the new key. 3. Confirm the new key can sign private requests. 4. Revoke the old key with `DELETE /v1/auth/api-keys/{accessKey}`. For a sign-out-everywhere action, send `DELETE /v1/auth/api-keys?all=true`. The signing key used for that request is revoked too. The full set of auth endpoints is documented in the [API Reference](https://docs.silhouette.exchange/rfq/api/reference.md). ## Rate limits[​](#rate-limits "Direct link to Rate limits") Authenticated traffic is limited per account. Traffic before authentication is limited per client IP. | Scope | Limit | | ----------------------------------------------- | ------------------------------------------------------- | | Signed REST requests and frames on `/v1/rfq/ws` | 20 per second, burst 60, per account, one shared budget | | Ladders on `/v1/rfq/prices/ws` | 20 per second, burst 60, per account and instrument | | Login, WebSocket upgrades, and the `auth` frame | 100 per second, burst 200, per client IP | | Concurrent `/v1/rfq/ws` sessions | 8 per account; a maker holds one | | Topic subscriptions | 256 per account, across all sessions | | `/v1/rfq/prices/ws` sockets | One per maker | Not charged: `ping` and `pong` at 10 seconds apart or slower, and `unsubscribe` on every topic except `openRfqs`. A refused REST request is a `429` with code `RATE_LIMITED` and a `Retry-After` header in whole seconds. A refused WebSocket frame is an `error` frame with code `RATE_LIMITED`, its `message` naming the wait; the socket and its subscriptions are unchanged. A refused ladder is dropped and the previous ladder stays live. --- # Your first trade This is the golden path for a taker: one manually accepted RFQ, driven over the [REST API](https://docs.silhouette.exchange/rfq/api/rest.md) with live updates from the [WebSocket API](https://docs.silhouette.exchange/rfq/api/websocket.md). The calls below run against the production host, `rfq-api.silhouette.exchange`; see [Signing requests](https://docs.silhouette.exchange/rfq/api.md#signing-requests) for the `hmac_headers` helper the REST calls below rely on. ## 1. Mint credentials[​](#1-mint-credentials "Direct link to 1. Mint credentials") Follow the [login flow](https://docs.silhouette.exchange/rfq/api.md#login-flow): request a nonce with `POST /v1/auth/challenge`, sign the SIWE message with your wallet, and submit it to `POST /v1/auth/api-keys`. Keep the returned `accessKey` and `secret`; the secret is shown once. ## 2. Connect the socket and subscribe[​](#2-connect-the-socket-and-subscribe "Direct link to 2. Connect the socket and subscribe") Open `wss://rfq-api.silhouette.exchange/v1/rfq/ws`, authenticate with an `auth` frame (the credential pair signs a canonical `GET /v1/rfq/ws`), then subscribe to your RFQ statuses and the competing quotes on them: ``` { "kind": "auth", "accessKey": "", "signedAt": 1769600000000, "signature": "" } ``` The server confirms with `{ "kind": "health", ... }`. Then: ``` { "kind": "subscribe", "topic": "rfqStatus" } { "kind": "subscribe", "topic": "quotes" } ``` Each is acknowledged with a `subscribed` frame echoing the topic. ## 3. Submit the RFQ over REST[​](#3-submit-the-rfq-over-rest "Direct link to 3. Submit the RFQ over REST") Buy 0.5 TSLAX for at most 1000 USDC, with a 30-second quote window: ``` curl https://rfq-api.silhouette.exchange/v1/rfq/requests \ --request POST \ --header "Content-Type: application/json" \ # plus the three signed headers from hmac_headers --data '{ "instrumentId": "TSLAX-USDC-SPOT", "side": "BUY", "baseQty": "0.5", "quoteLimit": "1000", "windowMs": 30000, "idempotencyKey": "0193b6f1-7c10-7d6c-8000-abc123456789" }' ``` `quoteLimit` is the most you will pay for `baseQty`, taker fee included. Some markets also set a smallest order value they take, published on the instrument as `minQuoteNotional`: on a `BUY` your limit has to cover that figure plus the fee charged on it, or the call returns `400 BELOW_MIN_NOTIONAL` with `details.minQuoteNotional` naming what to resize from. Read the field from `GET /v1/rfq/instruments` before you send; a market that sets no minimum omits it. See [Minimum order value](https://docs.silhouette.exchange/rfq/overview.md#minimum-order-value). The `202` response carries the RFQ's identity and the auction deadline the clamp settled on: ``` { "rfqId": "rfq_...", "status": "PENDING", "auctionEndsAt": 1769600030000 } ``` ## 4. Watch the quotes stream in[​](#4-watch-the-quotes-stream-in "Direct link to 4. Watch the quotes stream in") As makers respond, the `quotes` subscription pushes a `quoteUpdate` frame per competing quote. `takerTotal` is the all-in amount you would pay, taker fee included — it is the figure your `quoteLimit` bounds, so a quote wins only if its `takerTotal` is at or under it: ``` { "kind": "quoteUpdate", "rfqId": "rfq_...", "quoteId": "qt_...", "status": "SUBMITTED", "takerTotal": "992.50", "receivedAt": 1769600005000, "acceptableForMs": 30000 } ``` `acceptableForMs` is the maker's own window, counted from `receivedAt`; it is absent when the maker named none, and the quote then stands until the auction closes. ## 5. Accept the best quote[​](#5-accept-the-best-quote "Direct link to 5. Accept the best quote") Before the auction ends, accept over REST: ``` curl https://rfq-api.silhouette.exchange/v1/rfq/requests/rfq_.../accept \ --request POST \ --header "Content-Type: application/json" \ # plus the three signed headers from hmac_headers --data '{ "quoteId": "qt_..." }' ``` ## 6. Watch it settle[​](#6-watch-it-settle "Direct link to 6. Watch it settle") The `rfqStatus` subscription streams each transition. Acceptance moves the RFQ to `QUOTED` while settlement is in progress, and settlement completes it: ``` { "kind": "rfqStatus", "id": "rfq_...", "status": "SETTLED", "txHash": "0x..." } ``` A trade is an RFQ in `SETTLED`, carrying its settlement transaction hash. If nothing conforming arrived, or you let the deadline pass, the RFQ ends `FAILED` instead and any locked funds are released; `CANCELLED` is reserved for a request you cancelled yourself, which you may do while it is `PENDING` and before its `auctionEndsAt`. The [lifecycle table](https://docs.silhouette.exchange/rfq/overview.md#trade-lifecycle) covers every outcome. That is the whole loop: REST for every action, the socket for everything that happens in between. From here, read balances with `GET /v1/rfq/balances` (or subscribe to `balances`), and explore the full surface in the [API Reference](https://docs.silhouette.exchange/rfq/api/reference.md). --- # RFQ REST API The REST API carries every client-initiated action: authentication, RFQ submission and acceptance, maker quoting, and balance and funding operations. Reads are available over REST too; for live updates, pair it with the [WebSocket API](https://docs.silhouette.exchange/rfq/api/websocket.md). Endpoint-level documentation lives in the interactive [REST reference](https://docs.silhouette.exchange/rfq/api/reference.md), rendered from the OpenAPI 3.1 spec at [`/api/rfq-openapi.yaml`](https://docs.silhouette.exchange/assets/files/rfq-openapi-274f80955669a8308555ec1d652cd4f3.yaml). ## Surface[​](#surface "Direct link to Surface") All paths are under `https://rfq-api.silhouette.exchange/v1`. Private endpoints require [HMAC-signed requests](https://docs.silhouette.exchange/rfq/api.md#signing-requests). | Area | Paths | What it covers | | ------------ | -------------------------------------------------------------- | ------------------------------------------------------------------------------ | | Auth | `/v1/auth/*` | SIWE login challenge, API key minting, listing, and revocation | | Instruments | `/v1/rfq/instruments*`, `/v1/rfq/tokens*` | Public instrument and token metadata, including top-of-book | | RFQs (taker) | `/v1/rfq/requests*` | Submit, read, cancel, list quotes on, and accept an RFQ | | Maker | `/v1/rfq/maker/*` | Open RFQs for approved instruments, quote submission and cancellation | | Balances | `/v1/rfq/balances`, `/v1/rfq/ledger` | Balance state, one line per token and custody rail, and the append-only ledger | | Funding | `/v1/rfq/funding`, `/v1/rfq/deposits*`, `/v1/rfq/withdrawals*` | Funding details, deposits, and withdrawals | ## Conventions[​](#conventions "Direct link to Conventions") * Identifiers are opaque, type-prefixed strings (`rfq_`, `qt_`, `dep_`, `wd_`). Store and return them verbatim; never parse them. * Amounts are exact decimal strings in human-readable units, never floating point. How many decimal places a request may carry depends on where the amount is paid from, so a withdrawal finer than its custody rail accepts is refused as `AMOUNT_OVER_PRECISE`, with `details.maxDecimals` naming the limit. * A market can set a smallest order value it takes, published on the instrument as `minQuoteNotional`. On a `BUY` the RFQ's `quoteLimit` must cover it plus the taker fee charged on it; a smaller request is refused as `BELOW_MIN_NOTIONAL`, with `details.minQuoteNotional` naming the figure. A market that sets no minimum omits the field. A spot `baseQty` must also be a multiple of the instrument's published `baseQtyIncrement`; one off the step is refused as `BASE_QTY_OFF_INCREMENT`, with `details.increment` naming the step. * Instants are Unix milliseconds with an `At` suffix (`auctionEndsAt`); durations are milliseconds with `Ms` (`windowMs`, `acceptableForMs`). The exception is the `Deadline` suffix (`settlementDeadline`, `deliveryDeadline`), which carries Unix **seconds**: these are on-chain-native values relayed verbatim, so they stay in the unit the chain reads. * Lists are cursor-paginated: `limit` and `cursor` in, `{ items, hasMore, nextCursor }` out. `nextCursor` is always present, and null when `hasMore` is false. * Mutating submissions carry a client-generated `idempotencyKey` (UUID). A replay under the same key returns the originally created resource instead of executing again. A replay whose terms contradict the original, such as a withdrawal naming a different `rail` from the one that paid, is refused instead. * Errors carry a stable machine-readable `code` and a human-readable `message`. Branch on `code`; the set grows additively, so treat an unknown code as a generic failure of its class. ## Generating clients[​](#generating-clients "Direct link to Generating clients") The [OpenAPI Generator](https://openapi-generator.tech/) tool can generate strongly-typed client SDKs from the REST spec in many languages, including TypeScript, Python, Java, Go, and Rust. ``` # Install the OpenAPI Generator CLI npm install @openapitools/openapi-generator-cli -g # Generate a TypeScript Axios client openapi-generator-cli generate \ -i https://docs.silhouette.exchange/api/rfq-openapi.yaml \ -g typescript-axios \ -o ./generated-client ``` ``` # Generate a Python client openapi-generator-cli generate \ -i https://docs.silhouette.exchange/api/rfq-openapi.yaml \ -g python \ -o ./generated-client ``` See the [OpenAPI Generator generators list](https://openapi-generator.tech/docs/generators) for all supported languages. --- # RFQ WebSocket API The WebSocket API streams live updates: RFQ and quote status, balance snapshots, and top-of-book prices. It is read-only: every client-initiated mutation goes over the [REST API](https://docs.silhouette.exchange/rfq/api/rest.md); the socket carries the handshake, the subscriptions, and the pushes. Frame-level documentation lives in the interactive [WebSocket reference](https://docs.silhouette.exchange/rfq/api/reference.md#websocket/description/introduction), rendered from the AsyncAPI 3.0 spec at [`/api/rfq-asyncapi.yaml`](https://docs.silhouette.exchange/assets/files/rfq-asyncapi-a9f26cf35c4a235cd9c3a3179e4f6b06.yaml). ## Connecting[​](#connecting "Direct link to Connecting") The shared client stream is `wss://rfq-api.silhouette.exchange/v1/rfq/ws`. Frames are JSON, tagged with a `kind` discriminator. After connecting, the client authenticates with an in-band `auth` frame (the credential pair from [SIWE login](https://docs.silhouette.exchange/rfq/api.md#login-flow) signs a canonical `GET /v1/rfq/ws`, the same recipe as a signed REST request) and the server replies with a `health` frame. The socket is authenticated once; later frames carry no signature. Liveness is an application-level keepalive: send `{"kind": "ping"}` roughly every 15 seconds and the server answers `{"kind": "pong"}`. A reconnect needs a fresh `auth` frame and fresh subscriptions. Pinging faster than that cadence draws on the account's request budget. An account holds a bounded number of concurrent authenticated sessions, and a bounded number of topic subscriptions across them (see [rate limits](https://docs.silhouette.exchange/rfq/api.md#rate-limits)). A session beyond the first bound is answered `AUTH_REQUIRED` and closed, so close the old socket before reconnecting rather than opening another beside it. A `subscribe` beyond the second is answered `RATE_LIMITED` and leaves the socket and its existing subscriptions alone; re-subscribing to a topic the session already holds records nothing and is acknowledged rather than refused. ## Topics[​](#topics "Direct link to Topics") Dispatch is opt-in: after the `health` frame the server sends nothing until the client subscribes. A `subscribe` frame names a topic and is acknowledged with `subscribed`; `unsubscribe` opts back out. ``` { "kind": "subscribe", "topic": "prices", "instrumentId": "TSLAX-USDC-SPOT" } ``` | Topic | Scope | Streams | | ------------- | ------------------------------- | --------------------------------------------------------------------------------------------------------------------- | | `prices` | Public, per instrument | A `price` frame when the top of book changes, with the current top of book on subscribe | | `balances` | The authenticated user | A `balanceSnapshot` on every committed change, with a full snapshot on subscribe | | `rfqStatus` | The authenticated user's RFQs | An `rfqStatus` frame per status transition, with the user's open RFQs on subscribe | | `quotes` | The authenticated user's RFQs | A `quoteUpdate` frame per competing quote received, with up to 100 recent quotes on the user's open RFQs on subscribe | | `openRfqs` | Eligible makers, per instrument | An `rfq` frame per open RFQ on that instrument (live-only) | | `quoteStatus` | Makers only | A `quoteStatus` frame per transition of the maker's own quotes, with recent quotes replayed on subscribe | Topics with a baseline reply with current state on subscribe. On `quotes` that baseline is a `quoteUpdate` for each of up to 100 of the most recent quotes on the account's open RFQs, each carrying the status it has reached; read past that limit with `GET /v1/rfq/requests/{id}/quotes`. A quote committed as the subscription opens can arrive both in the baseline and as a live push, and the later `receivedAt` carries the current terms. `openRfqs` is live-only, so a maker joining mid-auction recovers what it missed over REST. Balance snapshots are full state delivered in per-user commit order, so the last snapshot a subscriber sees is always its true current balance. A `price` frame is the current top of book, not a record of a change. When delivery falls behind, frames skip the values in between, and a frame can repeat the top of book the subscriber already holds. Apply frames in the order they arrive and let each replace the one before. The two maker topics are refused with `UNSUPPORTED_CHANNEL` when the account does not qualify, and the socket stays open. `quoteStatus` needs an active maker record; `openRfqs` additionally needs approval for the instrument's pair and at least one operated settlement adapter, re-checked as each RFQ is pushed rather than only at subscribe. Errors arrive as `{"kind":"error","code":…,"message":…}`. `AUTH_REQUIRED` closes the session, and `INVALID_MESSAGE` closes it too unless it answers a frame sent out of sequence. `UNSUPPORTED_CHANNEL`, `RATE_LIMITED`, `INVALID_INSTRUMENT_ID`, `UNKNOWN_INSTRUMENT` and `UNAVAILABLE` refuse the offending frame and leave the socket open; `UNAVAILABLE` changed nothing, so retry the frame. ## Maker price ingest[​](#maker-price-ingest "Direct link to Maker price ingest") Makers publish indicative price ladders to a separate, maker-only socket at `wss://rfq-api.silhouette.exchange/v1/rfq/prices/ws`. The HTTP upgrade request is authenticated with the standard [HMAC headers](https://docs.silhouette.exchange/rfq/api.md#signing-requests) over a canonical `GET /v1/rfq/prices/ws`, and the account must be an active maker operating at least one settlement adapter; approval to quote a market is not enough on its own. Each message is a bare ladder object with no `kind` envelope. Eligibility is re-read while the socket is open, so a maker that stops qualifying has its ladders purged from the public book and its socket closed, and redials once it can settle again. Taker price consumption stays on the `prices` topic of the shared stream. Errors on this socket use the same `{"kind":"error","code":…}` envelope as the shared stream, so one reader dispatching on `kind` handles both. --- # HyperCore Market Making This guide is for market makers quoting HyperCore instruments on Silhouette's RFQ surface. HyperCore has two settlement adapters. They share the API but settle in fundamentally different ways, so each has its own page. | | [Spot](https://docs.silhouette.exchange/rfq/market-making/hypercore/spot.md) | [Perpetuals](https://docs.silhouette.exchange/rfq/market-making/hypercore/perpetuals.md) | | ------------------ | -------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | | Settlement mode | `HYPERCORE_SPOT` | `HYPERCORE_PERP` | | Example instrument | `HYPE-USDC-SPOT` | `BTC-USDC-PERP` | | Custody | Silhouette's HyperCore omnibus holds both legs | None. Each party holds its own margin at Hyperliquid. | | Your quote carries | The two legs, plus a `promised` flag | The two legs, plus a pre-signed post-only order and its cancel | | How a win settles | On Silhouette's books from inventory you deposited, or by your spot-send after winning | Silhouette crosses your order with the taker's on Hyperliquid's book | | Acceptance | Automatic or manual | Manual only | Neither adapter involves a contract. On spot, the only onchain action you take is a `spotSend` from your own HyperCore account. On perps, you sign Hyperliquid orders and Silhouette broadcasts them. One maker identity can operate both adapters. ## Shared plumbing[​](#shared-plumbing "Direct link to Shared plumbing") Everything outside settlement works as it does for every maker, so this guide does not repeat it. Read the [RFQ overview](https://docs.silhouette.exchange/rfq/overview.md) and the [RFQ API](https://docs.silhouette.exchange/rfq/api.md) first. * **Credentials.** Log in with SIWE to mint an access key and HMAC secret, and sign every private request. See [authentication](https://docs.silhouette.exchange/rfq/api.md#authentication). * **Receiving RFQs.** Open the [WebSocket](https://docs.silhouette.exchange/rfq/api/websocket.md), subscribe to `openRfqs` for each instrument and to `quoteStatus`, and receive `rfq` frames. Holding the `openRfqs` subscription is what makes you eligible to be quoted, together with pair approval and the adapter registered at onboarding. * **Quoting.** Submit with `POST /v1/rfq/maker/quotes`. Re-submitting for the same RFQ replaces your quote, and `POST /v1/rfq/maker/quotes/{quoteId}/cancel` withdraws it before selection. * **Outcomes.** Every transition of your quotes arrives on `quoteStatus`, and the topic replays recent quotes on reconnect. `GET /v1/rfq/maker/quotes` is the REST equivalent. The [xStocks quoting page](https://docs.silhouette.exchange/rfq/market-making/xstocks/quoting.md) walks through this loop frame by frame. --- # HyperCore Perpetuals Perpetuals such as `BTC-USDC-PERP` settle through the `HYPERCORE_PERP` adapter by **matched execution**. Nothing is custodied: you and the taker each hold margin in your own Hyperliquid perp account. Your quote carries a pre-signed post-only order at your price, and a pre-signed cancel for it. The taker accepts with a pre-signed immediate-or-cancel (IOC) order at the same price and size. Silhouette broadcasts the orders in a fixed sequence and reports what the book did. You end up holding whatever position your order produced, at Hyperliquid. Silhouette can broadcast only what you signed. It cannot change, re-price, or re-time an order, so any failure that would need a new price ends the RFQ, and the taker opens a new one. Perp RFQs always use manual acceptance, because the taker must sign its order at your quoted price. A perp RFQ that nobody accepts before `auctionEndsAt` fails. The taker locks no funds, and `baseQty` is in Hyperliquid's size units for the asset. ## The quote[​](#the-quote "Direct link to The quote") ``` { "rfqId": "rfq_0193b6f17c107d6c8000abc123456789", "instrumentId": "BTC-USDC-PERP", "side": "BUY", "settlementMode": "HYPERCORE_PERP", "makerPays": { "token": "BTC", "amount": "0.5" }, "makerReceives": { "token": "USDC", "amount": "32000" }, "settlement": { "makerOrder": { "action": { "type": "order", "orders": [{ "a": 0, "b": false, "p": "64000", "s": "0.5", "r": false, "t": { "limit": { "tif": "Alo" } }, "c": "0x00000000000000000000000000000abc" }], "grouping": "na" }, "nonce": 1716284400123, "signature": { "r": "0x…", "s": "0x…", "v": 27 } }, "makerCancel": { "action": { "type": "cancelByCloid", "cancels": [{ "asset": 0, "cloid": "0x00000000000000000000000000000abc" }] }, "nonce": 1716284400124, "signature": { "r": "0x…", "s": "0x…", "v": 27 } } } } ``` The base leg is the size, and the other leg is the notional in the quote token. `settlement` is required. It holds two signed Hyperliquid exchange actions, each an `action`, a `nonce`, and a `signature`, exactly as Hyperliquid signing tooling produces them. Both must be signed by the perp account registered for you. Silhouette refuses a maker payload signed by any other key, including an API wallet. `makerOrder` must be: * one limit order, on the side opposite the taker's (`b: false` against a taker `BUY`); * at your quoted price `p`, for the full RFQ size `s`, agreeing with the quote's legs; * post-only (`"tif": "Alo"`), so it rests or is rejected but never crosses; * not reduce-only (`r: false`); * tagged with a client order id `c`. `makerCancel` must be one `cancelByCloid` whose `asset` and `cloid` match the order's `a` and `c`. Round the price and size to Hyperliquid's tick and `szDecimals` rules before you sign. Silhouette checks every one of these rules when you submit and again when the taker accepts, and refuses a quote that breaks any of them. ## Execution[​](#execution "Direct link to Execution") When the taker accepts, Silhouette: 1. Broadcasts your post-only order. If the market has moved through your price, the order is rejected and the RFQ fails. 2. Broadcasts the taker's IOC. It fills against your order, or against any better-priced order ahead of yours, and cancels its own remainder. 3. Broadcasts your cancel, on every path, to clear any unfilled part of your order. 4. Settles the RFQ for the taker's filled size if it is above zero, and fails it otherwise. The cross is not atomic. If a stranger's better-priced order sits ahead of yours, the taker fills there first and you fill less. If a stranger lifts your order before the IOC lands, you keep that fill and the RFQ fails. ## Outcomes[​](#outcomes "Direct link to Outcomes") Your quote goes from `SUBMITTED` straight to `SETTLED`, with no `SELECTED` step. A quote the taker did not accept ends `NOT_SELECTED` or `EXPIRED`. An accepted quote whose cross fails ends `FAILED`. ``` { "kind": "quoteStatus", "rfqId": "rfq_0193b6f17c107d6c8000abc123456789", "quoteId": "qt_0193b6f19a207e448000def987654321", "instrumentId": "BTC-USDC-PERP", "side": "BUY", "status": "SETTLED", "makerPays": { "token": "BTC", "amount": "0.5" }, "makerReceives": { "token": "USDC", "amount": "32000" }, "receivedAt": 1716284400000, "settledAt": 1716284401500, "perpFilledSize": "0.5", "perpFillAvgPx": "63996" } ``` `perpFilledSize` and `perpFillAvgPx` are the taker's realised fill. A partial fill reports the partial size. The frame has no `txHash`, so read your own position and fills from Hyperliquid. ## Nonces[​](#nonces "Direct link to Nonces") Each payload's nonce is the millisecond timestamp you sign it with, and Hyperliquid rejects a nonce that is too old. An acceptance that arrives long after you quoted can therefore fail on a stale nonce. Sign fresh payloads for every quote, and set `acceptableForMs` so the quote cannot be accepted after its nonces have aged out. ## Fees[​](#fees "Direct link to Fees") You pay Hyperliquid's maker fee on the fill, and funding on the position. Silhouette charges you nothing on this adapter. Any builder fee is charged to the taker's order, not yours. ## Onboarding[​](#onboarding "Direct link to Onboarding") 1. Fund a Hyperliquid perp account. Its key signs your orders and cancels, and Silhouette registers it as your settlement address. 2. Log in with SIWE from that account and mint credentials. 3. On testnet, answer a small perp RFQ and confirm both the `SETTLED` frame and the position at Hyperliquid. --- # HyperCore Spot Spot pairs such as `HYPE-USDC-SPOT` settle through the `HYPERCORE_SPOT` adapter against Silhouette's HyperCore omnibus, the HyperCore spot account that holds every balance Silhouette custodies there. Each quote is one of two kinds, set per quote by the `promised` flag: * **Inventory** (`promised: false`, the default). You already hold the maker token in the omnibus. A win settles on Silhouette's books in the same transaction that selects it, and nothing moves on HyperCore. * **Promised** (`promised: true`). You do not hold the maker token. A win obliges you to spot-send it to the omnibus within your delivery window. You hold one quote per RFQ on this adapter. Re-submitting replaces it, and can switch it from one kind to the other. ## Your venue account[​](#your-venue-account "Direct link to Your venue account") Your venue account is the HyperCore spot account you deposit from, deliver from, and withdraw to. Silhouette registers it at onboarding. It can be the address you log in with, or a separate one. Every movement of money on this adapter keys on it: your inventory is held against it, and a delivery counts only if it comes from it. Its key must sign every spot-send on this page. ## Funding[​](#funding "Direct link to Funding") `GET /v1/rfq/funding` returns the omnibus address as `depositAddress` and the HyperCore network as `hypercore.chain`. To deposit, `spotSend` the token from your venue account to the omnibus. The deposit credits your `available` balance on the `HYPERCORE` rail as soon as Silhouette observes it, with no confirmations to wait for. Subscribe to the `balances` topic to see it land. A deposit is credited to whoever sent it. Send directly from your venue account and sign the transfer with its key. A transfer forwarded by an exchange, or relayed by a bridge, is attributed to the intermediary or held for manual review. To withdraw, call `POST /v1/rfq/withdrawals` with `"rail": "HYPERCORE"`. It pays a spot-send to your own address, and funds never move between rails. Size the request against the balance line's `withdrawable`. ## Inventory quotes[​](#inventory-quotes "Direct link to Inventory quotes") ``` { "rfqId": "rfq_0193b6f17c107d6c8000abc123456789", "instrumentId": "HYPE-USDC-SPOT", "side": "BUY", "settlementMode": "HYPERCORE_SPOT", "makerPays": { "token": "HYPE", "amount": "10" }, "makerReceives": { "token": "USDC", "amount": "200" } } ``` Neither kind carries a `settlement` payload, and a quote that includes one is refused. An inventory quote is valid only while your `available` balance of the `makerPays` token on the `HYPERCORE` rail covers it. A quote your balance does not cover is never selected, and you receive no push for it. The balance is checked again at selection, so if another win has drawn it down in the meantime, the quote is passed over. A winning inventory quote produces one `quoteStatus` frame, `SETTLED`, with no `SELECTED` before it. A `balanceSnapshot` showing both legs follows. The frame has no `txHash`, because nothing moved on HyperCore. ## Promised quotes[​](#promised-quotes "Direct link to Promised quotes") A promised quote is the same body with `"promised": true`. No balance check runs. Its `makerPays` amount must exceed the token's late-delivery return fee, described under [late deliveries and defaults](#late-deliveries-and-defaults). ### The cascade[​](#the-cascade "Direct link to The cascade") Inventory and promised quotes compete on price alone. When a promised quote wins, Silhouette builds a **cascade chain**: the winner at position 0, then every other conforming promised quote, best price for the taker first. Any inventory quotes end `NOT_SELECTED`. Each position gets its own maker's delivery window, agreed at onboarding and one hour by default, and the windows run back to back: ``` position 0 (winner) |── window ──| position 1 (backup) |── window ──| position 2 (backup) |── window ──| ``` * The first position to deliver within its own window settles the RFQ, at that position's quoted price. Every position was checked against the taker's limit when the chain was built. * A position that misses its window loses the trade, and the chain moves on. * If every window closes without a delivery, the RFQ fails and the taker is refunded. Once the chain is built, its quotes cannot be re-priced or cancelled. ### Frames[​](#frames "Direct link to Frames") The winner receives `PENDING_DELIVERY` with its window, in unix milliseconds. `makerPays` is what you owe: ``` { "kind": "quoteStatus", "rfqId": "rfq_0193b6f17c107d6c8000abc123456789", "quoteId": "qt_0193b6f19a207e448000def987654321", "instrumentId": "HYPE-USDC-SPOT", "side": "BUY", "status": "PENDING_DELIVERY", "makerPays": { "token": "HYPE", "amount": "10" }, "makerReceives": { "token": "USDC", "amount": "200" }, "receivedAt": 1716284400000, "windowStartsAt": 1716284400000, "windowEndsAt": 1716288000000 } ``` Each backup receives `SUBMITTED` with its `position`, counted from 1, and the window its turn would get. If the chain reaches a backup, it receives `PENDING_DELIVERY` when its window opens. A backup may deliver early: the delivery settles the moment its window opens, or is returned if an earlier position delivers first. | Final status | Who gets it | Meaning | | -------------- | ---------------------------------------------------- | -------------------------------------------------------------------------------------- | | `SETTLED` | The position that delivered | Done. `makerReceives` is credited to your `available` balance on the `HYPERCORE` rail. | | `DEFAULTED` | The winner, if its window closed without a delivery | Recorded against you. | | `NOT_SELECTED` | Backups, when an earlier position delivered | Nothing owed. | | `FAILED` | Backups, when every window closed without a delivery | Nothing owed, and not recorded against you. | ### Delivering[​](#delivering "Direct link to Delivering") Deliver with a `spotSend` from your venue account, signed by its key and submitted to Hyperliquid's [exchange endpoint](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint): ``` { "type": "spotSend", "hyperliquidChain": "Mainnet", "signatureChainId": "0xa4b1", "destination": "0x6666666666666666666666666666666666666666", "token": "HYPE:0x0d01dc56dcaaca66ad901c959b4011ec", "amount": "10", "time": 1716284405000 } ``` * `destination` is the omnibus address from `GET /v1/rfq/funding`. The address above is a placeholder. * `token` uses Hyperliquid's `:` form, and the bare symbol is rejected. Token ids come from Hyperliquid's `spotMeta`. * `amount` is exactly the quote's `makerPays.amount`. * `time` is the nonce. If a send times out, retry the identical action with the same nonce. HyperCore transfers carry no memo, so Silhouette matches a delivery to your quote by sender, token, and exact amount. Any other transfer from you is a deposit. A deposit that happens to equal an open obligation's amount is taken as that delivery, so keep top-ups at sizes no open promise shares. When two open obligations have the same amount, one transfer settles the older. A delivery that landed inside the window counts even if Silhouette observes it late. Don't rely on the socket alone to know what you owe. `GET /v1/rfq/maker/quotes?status=PENDING_DELIVERY` lists every delivery still outstanding. Poll it well inside your window, and mark an obligation done only once the send succeeds. An accidental second send is credited back to you as a deposit. ### Late deliveries and defaults[​](#late-deliveries-and-defaults "Direct link to Late deliveries and defaults") Silhouette returns a delivery it cannot use to your venue account automatically. That covers a delivery that arrives after your window closed, and an early backup delivery overtaken by an earlier position. The return is net of a flat per-token fee, about a dollar's worth of the token, set at onboarding. A winner that misses its window ends `DEFAULTED`, and the default is recorded against the maker. Silhouette may suspend a maker that defaults. A suspended maker receives no RFQs and cannot withdraw until the default has been reviewed. A backup that lets its window pass is not penalised. ## Onboarding[​](#onboarding "Direct link to Onboarding") 1. Open a HyperCore spot account to serve as your venue account. 2. Log in with SIWE and mint credentials. If your venue account is not the address you log in with, tell Silhouette. 3. If you will quote promised, agree a delivery window. The default is one hour. 4. If you will quote from inventory, deposit it before you start quoting. 5. On testnet, take one inventory RFQ and one promised RFQ through to `SETTLED`. --- # xStocks Market Making This guide is for market makers integrating with Silhouette's RFQ surface to quote and settle **xStocks**: Backed's tokenized US-equity ERC-20 series deployed on HyperEVM, such as `TSLAx`, `AAPLx`, and `SPYx`. Each xStock trades against USDC as an RFQ instrument (for example `TSLAX-USDC-SPOT`): takers request a price, makers compete to fill it, and the winning quote settles on-chain. By the end of the four pages you will be able to authenticate to the API, receive open RFQs on the xStock instruments you are approved for, price and submit quotes, deploy the settlement contract those quotes settle through, and take a fill from selection to settled, in either of the two settlement modes this venue supports. The defining property of this venue, stated up front: **you deploy your own settlement wrapper contract**. On Silhouette's other settlement adapters a maker approves a Silhouette-deployed contract; here the wrapper is your code, deployed by you on HyperEVM, and it is the only on-chain code you contribute. Silhouette reviews the wrapper's source and pins its deployed code hash before it may settle, and every settlement authorization Silhouette signs names your wrapper, and only your wrapper, as the contract allowed to act on it. If you have not met the RFQ surface before, read the [RFQ overview](https://docs.silhouette.exchange/rfq/overview.md) for the lifecycle and the [RFQ API](https://docs.silhouette.exchange/rfq/api.md) overview for authentication and transports first. This guide assumes both. ## Two settlement modes[​](#two-settlement-modes "Direct link to Two settlement modes") Both modes settle atomically: the taker's USDC and your xStock change hands in one transaction, or the whole transaction reverts and nothing moves. They differ in where the xStock comes from. **Inventory mode** (`XSTOCKS_INVENTORY`): you hold xStock inventory inside your wrapper and deliver from that balance on each fill. At fill time the wrapper pulls the taker's USDC from the omnibus through Permit2 and transfers the xStock back to the omnibus from its own holdings, in the same transaction. This is the simplest mode to run: quoting needs no per-quote third-party interaction, but you fund the wrapper and top it up on your own schedule, and the wrapper's own ERC-20 balance caps the size of any single fill. **xChange mode** (`XSTOCKS_XCHANGE`): inventory-less atomic settlement. Your wrapper composes the USDC pull with a call into Backed's `AtomicSwapUpgradeable`, which sources the xStock against the underlying equity exposure you hold off-chain as a Backed Authorized Participant. You hold no on-chain inventory; for each RFQ you quote, you request a Backed-signed `SwapMessage` from Backed and attach it to the quote. What you manage is cash, your AP allowance, and the Backed API. The swap does not have to be struck at the price you quoted. Your spread is whatever you do not pass on to Backed, or whatever you take from Backed above what you quoted, and it stays in your wrapper for you to withdraw. Silhouette bounds both legs so that difference never comes out of the taker: the omnibus pays the taker amount you quoted and receives the maker amount you quoted, whichever leg your spread sits on. The [settlement page](https://docs.silhouette.exchange/rfq/market-making/xstocks/settlement.md) has the exact bounds. | | Inventory (`XSTOCKS_INVENTORY`) | xChange (`XSTOCKS_XCHANGE`) | | ------------------- | ------------------------------------------------------- | ------------------------------------------------------------------------- | | On-chain inventory | Held in your wrapper; its balance caps single-fill size | None | | Backed relationship | None required | Authorized Participant; your wrapper allowlisted with Backed | | Per-quote work | Price and submit | Request a Backed-signed `SwapMessage` from Backed, attach it to the quote | | You manage | Wrapper funding, top-ups, withdrawing proceeds | Cash, AP allowance, the Backed API | | Wrapper interface | `IInventoryWrapper` | `IXstocksXchangeWrapper` | A wrapper is bound to one mode. A maker running both modes deploys two wrappers under one maker identity, and may then quote a single RFQ through both modes at once, one quote per adapter. ## Parties and trust[​](#parties-and-trust "Direct link to Parties and trust") Five parties touch an xStocks settlement. What each does, and what you are relying on: | Party | What it does | What is assumed of it | | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | You (the maker) | Prices RFQs and submits quotes over the authenticated API; submits the wrapper's `fill()` transaction and pays its gas. | Nothing, at the protocol level. Your on-chain authority is mediated entirely by your wrapper's bytecode, which Silhouette reviews at onboarding. | | Your wrapper | The contract you deploy. Consumes the Silhouette-signed Permit2 authorization and produces the maker leg in the same transaction, then emits the `Filled` event Silhouette observes. | Nothing, at the protocol level. The authorization binds your wrapper as its only permitted spender and binds the maker leg into the witness; the fill succeeds or the whole transaction reverts. Silhouette pins the reviewed code hash before the wrapper may settle. | | Omnibus | Holds Silhouette users' USDC and xStock balances on HyperEVM. It is the counterparty on every fill: your wrapper pulls the taker token from it and delivers the xStock to it. Signing one Permit2 authorization per selected quote is Silhouette's entire on-chain action on this adapter. | Silhouette signs only after selecting a winning quote and validating it; the signature is narrowly scoped to that quote (see below). | | Permit2 | The canonical Uniswap deployment at `0x000000000022D473030F116dDEE9F6B43aC78BA3`, identical on every EVM chain. Executes the USDC pull when, and only when, the call matches the signed authorization. | Audited and immutable. Its nonce bitmap provides replay protection, and its spender check binds each authorization to the one contract named in it. | | Backed's `AtomicSwapUpgradeable` (xChange only) | Backed-operated HyperEVM contract that executes the two transfer legs of a Backed-signed `SwapMessage`: it pulls the USDC from your wrapper and transfers the xStock from Backed's transfer account. | It is upgradeable, so Silhouette verifies its implementation before signing, and both your wrapper and Silhouette independently verify the delivered amounts; a short delivery reverts rather than settling. | ## Bounded authorization[​](#bounded-authorization "Direct link to Bounded authorization") The property that makes a maker-deployed contract safe for both sides is that the authorization it consumes is narrow. For each quote it selects, Silhouette signs exactly one Permit2 `PermitWitnessTransferFrom`. That signature names: * the taker token and the exact quoted amount: nothing else can be pulled; * your wrapper as the only permitted spender: no other contract can consume it; * the quote id as the nonce: it settles that quote once, and never again; * a deadline no later than the RFQ's settlement deadline: after it, the authorization is dead; * your maker leg, bound into the witness: the xStock and amount you quoted (inventory), or the exact Backed `SwapMessage` Silhouette validated together with the amount the omnibus is owed out of it (xChange). The signature cannot be reused to pull a different token or amount, redirected to a different spender, or replayed to settle a different quote. Because the witness binds the maker leg, your wrapper cannot deliver anything other than what was quoted while still consuming the pull. Permit2 burns the nonce only on a successful fill, so a reverted transaction leaves the authorization intact until its deadline. The exact binding of every field is on the [settlement page](https://docs.silhouette.exchange/rfq/market-making/xstocks/settlement.md). ## Inventory mode, end to end[​](#inventory-mode-end-to-end "Direct link to Inventory mode, end to end") ## xChange mode, end to end[​](#xchange-mode-end-to-end "Direct link to xChange mode, end to end") In both modes the quote is submitted over REST and its outcome arrives as a `quoteStatus` push on the WebSocket; the `SELECTED` push carries the Silhouette-signed Permit2 payload your wrapper consumes. Everything between `fill(...)` and the `Filled` event is one transaction. ## How this guide is organized[​](#how-this-guide-is-organized "Direct link to How this guide is organized") * [Quoting](https://docs.silhouette.exchange/rfq/market-making/xstocks/quoting.md): connect, subscribe, price RFQs, submit quotes, track outcomes. * [Settlement](https://docs.silhouette.exchange/rfq/market-making/xstocks/settlement.md): what Silhouette signs, and the wrapper contract you deploy. For the RFQ surface itself, see the [RFQ overview](https://docs.silhouette.exchange/rfq/overview.md) and the [RFQ API](https://docs.silhouette.exchange/rfq/api.md). --- # Quoting xStocks This page is the off-chain half of the integration: everything between receiving an RFQ and holding a settlement authorization. The loop a maker runs is: 1. Authenticate and mint API credentials. 2. Open the WebSocket at `wss://rfq-api.silhouette.exchange/v1/rfq/ws` and authenticate it with an in-band `auth` frame. 3. Subscribe to `openRfqs` for each instrument you quote, and to `quoteStatus`. 4. Receive `rfq` frames as takers raise RFQs on your instruments. 5. Price each RFQ and submit a quote with `POST /v1/rfq/maker/quotes`. 6. Watch `quoteStatus` for the outcome. 7. On `SELECTED`, settle on-chain; see the [settlement page](https://docs.silhouette.exchange/rfq/market-making/xstocks/settlement.md). The transport split is absolute: **every client-initiated mutation goes over REST; the WebSocket is read-only**. The socket carries the handshake, the subscriptions, and the server's pushes, nothing else. There is no quote frame and no cancel frame; a quote is submitted and cancelled over HMAC-signed REST, and its outcome comes back as a push. ## Credentials[​](#credentials "Direct link to Credentials") Maker status is a property of the Silhouette account, not of the credential: Silhouette activates the account as a maker during onboarding, and any API key minted by that account is maker-scoped from then on. The maker-only topics and endpoints reject accounts that are not active makers. Mint credentials with the standard [login flow](https://docs.silhouette.exchange/rfq/api.md#login-flow) and sign every private request as described in [signing requests](https://docs.silhouette.exchange/rfq/api.md#signing-requests). Two facts worth internalising before automating: a signature's timestamp must be fresh within a 30-second window, and every authentication failure (missing header, bad signature, stale timestamp) is a `401`. ## Connecting[​](#connecting "Direct link to Connecting") Open `wss://rfq-api.silhouette.exchange/v1/rfq/ws`. Frames are JSON tagged with a `kind` discriminator. The first frame the client sends is `auth`: ``` { "kind": "auth", "accessKey": "", "signedAt": 1716284399000, "signature": "" } ``` The signature is over a canonical `GET /v1/rfq/ws` with an empty body, the same recipe as a signed REST request, so the canonical string is `"{signedAt}\nGET\n/v1/rfq/ws\n"`. `signedAt` plays the role the `Silhouette-API-Timestamp` header plays on REST: it must fall within 30 seconds of receipt, be unique per access key, and be assigned in increasing order at issuance. The server accepts the handshake with a `health` frame: ``` { "kind": "health", "userId": "0193b6f1-7c10-7d6c-8000-abc123456789", "isMaker": true } ``` `isMaker` reflects whether the account is registered as an active market maker; a maker integration should treat `isMaker: false` here as a configuration failure, since every subscription that matters on this page will be refused. Keepalive is application-level: send `{"kind": "ping"}` roughly every 15 seconds and the server answers `{"kind": "pong"}`. The socket is authenticated once; later frames carry no signature. A subscription lasts only for the life of the connection, so a reconnect needs a fresh `auth` frame and fresh subscriptions. ## Subscribing[​](#subscribing "Direct link to Subscribing") Dispatch is opt-in: after `health` the server sends nothing until the client subscribes. A maker holds two subscriptions: `openRfqs` per instrument, and `quoteStatus` once: ``` { "kind": "subscribe", "topic": "openRfqs", "instrumentId": "TSLAX-USDC-SPOT" } ``` ``` { "kind": "subscribe", "topic": "quoteStatus" } ``` Each is acknowledged with a `subscribed` frame echoing the selector: ``` { "kind": "subscribed", "topic": "openRfqs", "instrumentId": "TSLAX-USDC-SPOT" } ``` The `openRfqs` subscription is not just a data feed. **Holding the `openRfqs` subscription for an instrument is what makes a maker eligible to be quoted on it**, together with the standing eligibility a maker earns at onboarding. All three conditions must hold: an active maker record, approval for the instrument's pair, and at least one operated settlement adapter, on top of the live subscription. Silhouette dispatches each RFQ to every maker subscribed to its instrument. Publishing [price ladders](#publishing-price-ladders) is a separate concern and is not a precondition for receiving RFQs. Eligibility is re-checked when each RFQ is pushed, not only at subscribe. A maker whose approval or adapter registration lapses mid-session stops receiving RFQs on a subscription that was accepted earlier and is still open. The two topics replay differently on subscribe. `openRfqs` is live-only: nothing is replayed, and a maker that reconnects mid-auction recovers open RFQs over REST (`GET /v1/rfq/maker/requests`). `quoteStatus` replays the maker's recent quotes on subscribe, then streams every later transition. This is what makes it safe to lose the socket, covered under [tracking the outcome](#tracking-the-outcome). A subscribe to either topic from an account that does not qualify is refused with a recoverable `error` frame, and the socket stays open: ``` { "kind": "error", "code": "UNSUPPORTED_CHANNEL", "message": "not a registered market maker" } ``` Seven error codes exist, and the code names the condition rather than what happens to the socket: | Code | Disposition | | ----------------------- | ------------------------------------------------------------------- | | `AUTH_REQUIRED` | Closes the session. | | `INVALID_MESSAGE` | Closes the session, unless it answers a frame sent out of sequence. | | `UNSUPPORTED_CHANNEL` | Refuses the frame, socket stays open. | | `RATE_LIMITED` | Refuses the frame, socket stays open. | | `INVALID_INSTRUMENT_ID` | Refuses the frame, socket stays open. | | `UNKNOWN_INSTRUMENT` | Refuses the frame, socket stays open. | | `UNAVAILABLE` | Refuses the frame, socket stays open. Nothing changed, so retry it. | `INVALID_MESSAGE` covers a malformed or unrecognized frame, including any write-shaped message, since the socket carries no mutations. The maker price-ingest socket sends errors in this same envelope, so one reader dispatching on `kind` handles both sockets. ## Receiving an RFQ[​](#receiving-an-rfq "Direct link to Receiving an RFQ") Each open RFQ on a subscribed instrument arrives as an `rfq` frame carrying the `OpenRfq` resource: ``` { "kind": "rfq", "id": "rfq_0193b6f17c107d6c8000abc123456789", "instrumentId": "TSLAX-USDC-SPOT", "side": "BUY", "baseQty": "1", "autoAccept": false, "auctionEndsAt": 1716284399750, "settlementDeadline": 1716284430, "createdAt": 1716284279750 } ``` Note the field is `id`, not `rfqId`, and it carries the `rfq_` prefix; send it back verbatim as the quote's `rfqId` and never parse it. The frame carries what a maker needs to price the trade and nothing more; the taker's price bound deliberately stays private to the taker. * `auctionEndsAt` is unix milliseconds: the instant the RFQ stops accepting quotes and the winner is selected. The window is the taker's choice, so drive all timing off each RFQ's own `auctionEndsAt` rather than assuming a fixed length. * `settlementDeadline` is unix **seconds**: `auctionEndsAt` rounded up to the next whole second plus the operator's settlement headroom. It is the latest instant a win may settle. An inventory quote's Permit2 authorization is signed with exactly this value; an xChange quote's is signed with the expiry Backed stamped on its own swap, which must fall at or before it. Never derive it from `auctionEndsAt` yourself. * `autoAccept` says how the winner is chosen, not when. A taker may accept a quote early in either mode, so any quote can win before `auctionEndsAt`. With `autoAccept: true` the best conforming quote is selected at the auction end if nobody accepted sooner; with `false` only an explicit acceptance fills the request. Either mode locks the taker's worst-case pay side at submission, so the mode is no signal of when the taker's funds were committed. * `baseQty` is the quantity to quote on, in base-token units, and it has a side-dependent subtlety. On a `SELL` the taker fee is carved out of the base the taker delivers, so `baseQty` is what the maker actually buys; a quote priced on any other quantity cannot win. On a `BUY` it is the full size the taker asked for. `GET /v1/rfq/maker/requests` lists the same `OpenRfq` objects, cursor-paginated, for the instruments the maker is eligible to quote, applying the same three conditions as the `openRfqs` subscription: an active maker record, approval for the instrument's pair, and at least one operated settlement adapter. A maker failing any of them gets an empty page rather than an error. It serves a maker that prefers to poll, and it is the recovery path after a disconnect, since `openRfqs` replays nothing on subscribe. ## Submitting a quote[​](#submitting-a-quote "Direct link to Submitting a quote") Submit with `POST /v1/rfq/maker/quotes`, HMAC-signed like every private request. The required body fields are `rfqId`, `instrumentId`, `side`, `settlementMode`, `makerPays`, and `makerReceives`. The optional `acceptableForMs` sets the maker's own acceptance window, covered under [validity](#validity-and-mode-consistency). There is no `idempotencyKey` on a maker quote; re-submission has replace semantics instead, described below. The two legs are named from the maker's perspective and never flip meaning with the RFQ's side: `makerPays` is what the maker delivers, `makerReceives` is what it is paid. On a `BUY` the maker pays the base token and receives the quote token; on a `SELL` the reverse. An inventory-mode quote (`XSTOCKS_INVENTORY`) is the base body and nothing more, with no `settlement` payload: ``` { "rfqId": "rfq_0193b6f17c107d6c8000abc123456789", "instrumentId": "TSLAX-USDC-SPOT", "side": "BUY", "settlementMode": "XSTOCKS_INVENTORY", "makerPays": { "token": "TSLAX", "amount": "1" }, "makerReceives": { "token": "USDC", "amount": "200" }, "acceptableForMs": 30000 } ``` An xChange-mode quote (`XSTOCKS_XCHANGE`) carries the Backed-signed swap in the `settlement` object: the `swapMessage` you requested from Backed, and Backed's signature over it: ``` { "rfqId": "rfq_0193b6f17c107d6c8000abc123456789", "instrumentId": "TSLAX-USDC-SPOT", "side": "BUY", "settlementMode": "XSTOCKS_XCHANGE", "makerPays": { "token": "TSLAX", "amount": "1" }, "makerReceives": { "token": "USDC", "amount": "200" }, "acceptableForMs": 30000, "settlement": { "swapMessage": { "quoteId": "0x5555555555555555555555555555555555555555555555555555555555555555", "expiration": "1716284425", "incomingTransfer": { "from": "0x1111111111111111111111111111111111111111", "to": "0x2222222222222222222222222222222222222222", "token": "0x3333333333333333333333333333333333333333", "amount": "199000000" }, "outgoingTransfer": { "from": "0x2222222222222222222222222222222222222222", "to": "0x6666666666666666666666666666666666666666", "token": "0x4444444444444444444444444444444444444444", "amount": "1000000000000000000" } }, "backedSignature": "0x…" } } ``` The addresses are placeholders: `0x1111…` stands for your wrapper, `0x2222…` for Backed's transfer account (a value exchanged at onboarding), `0x3333…`/`0x4444…` for the USDC and TSLAx contracts, and `0x6666…` for Silhouette's omnibus. `expiration` is unix seconds, and it is Backed's value, not ours: Backed stamps it on the swap it signs, so relay it unchanged rather than overwriting it with the RFQ's `settlementDeadline`. It must still be in the future and at or before that deadline — above it sits five seconds inside one. Silhouette cross-checks every field of the `swapMessage` against the quote and the values registered at your onboarding before it will sign: parties and tokens for equality, the expiration against the deadline, and the two amounts directionally, as below. The on-chain meaning of each field is on the [settlement page](https://docs.silhouette.exchange/rfq/market-making/xstocks/settlement.md). The amounts are checked as bounds, not equalities, and above they differ on purpose. The taker pays the quoted 200 USDC, only 199 of it buys the stock, and the 1 USDC difference is your spread, left in your wrapper. `incomingTransfer.amount` may be at most the quoted taker amount, and `outgoingTransfer.amount` at least the quoted maker amount. To take your spread on the outgoing leg instead, ask Backed for more than you quoted and set `outgoingTransfer.to` to your own wrapper: the omnibus is owed the quote exactly, so a surplus sent to it is refused. This example delivers the exact quoted amount, so it names the omnibus directly. ### Two levels of token identity[​](#two-levels-of-token-identity "Direct link to Two levels of token identity") The single most important thing on this page: an xChange quote names its tokens at two levels, and they must agree. The quote's own legs name tokens by canonical uppercase **symbol** (`"USDC"`, `"TSLAX"`), with amounts as human-unit decimal strings. Symbols are the identity the whole account-facing API speaks: balances, instruments, quotes, everything. The inner `swapMessage` names ERC-20 **addresses**, with amounts in **raw base units** at each token's on-chain decimals. It has to: Backed signs over those bytes and the AtomicSwap contract reads them, so nothing about them may be re-shaped in transit. Silhouette resolves each leg's symbol and cross-checks the resolved address and converted amount against the matching `swapMessage` transfer at intake, so a maker that builds the two levels from different tokens is refused on submission, not discovered at settlement. Resolve a symbol to its contract address and decimals with `GET /v1/rfq/tokens`. One further identity to keep separate: `swapMessage.quoteId` is **Backed's** own per-quote identifier, living inside Backed's replay protection. It is distinct from **Silhouette's** `quoteId` (the `qt_`-prefixed id), which becomes the Permit2 nonce. The two never mix. ### Validity and mode consistency[​](#validity-and-mode-consistency "Direct link to Validity and mode consistency") * **Mode consistency.** An inventory quote must omit `settlement`; an xChange quote must carry it. A mismatch between the declared mode and the payload's presence or absence is refused at intake, as is a mode the account does not operate. * **Quote validity.** `acceptableForMs` is a duration in milliseconds, counted from the `receivedAt` Silhouette stamps on the quote, and it is optional. Omit it and no maker cutoff applies: the quote stands until the auction closes. Send it and anything below the venue floor (1000 ms by default) is refused. There is no upper bound, because a window outlasting the auction never bites; the auction close bounds acceptance either way. A duration rather than an instant means the maker's own clock can never shorten its window, and a re-quote restamps `receivedAt`, so each submission restarts the window rather than inheriting the first one. * **Settlement timing is not yours to set.** The quote carries no settlement deadline. Silhouette publishes one per RFQ as `settlementDeadline` and refuses any swap whose expiry runs past it. In xChange mode the expiry itself is Backed's: Silhouette adopts it and signs the Permit2 with it, because your wrapper rebuilds its own Permit2 deadline from that same field. ### Responses[​](#responses "Direct link to Responses") | Status | Meaning | | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `202` | The quote passed validation and joined the RFQ's collection. It also means accepted pending validation, when the verdict did not arrive in time or was lost after the quote had been taken in. | | `400` | Refused; the message names the reason. | | `503` | The quote never reached validation, or validation faulted before recording anything. Nothing was persisted and a retry is safe. | A quote accepted pending validation may or may not have joined the auction. Read `GET /v1/rfq/maker/quotes` to find out rather than re-submitting blind: a submission carries no idempotency key, so a fresh one replaces whatever already stands for the same adapter, which may be the very terms you are trying to confirm. The refusal reasons behind a `400`: * an unknown `rfqId`, or one no longer open; * an instrument the maker is not approved for; * a `settlementMode` naming an adapter the maker does not operate; * an `instrumentId` or `side` disagreeing with the RFQ's; * a missing `settlement` payload on a mode that requires one; * a `settlement` payload on a mode that settles from the maker's own inventory; * a payload that is not the shape its `settlementMode` routes it to; * a payload that fails validation against the third party and the quote's own economics. ### Re-pricing[​](#re-pricing "Direct link to Re-pricing") A maker holds one live quote per adapter on an RFQ. Re-submitting for the same RFQ and the same adapter replaces that quote's terms in place; that is how a maker re-prices as the market moves inside the auction window. A maker operating both modes may quote one RFQ twice, once per mode, and the two quotes compete independently. ### Winning[​](#winning "Direct link to Winning") Selection at the deadline (or at an early taker accept) checks each candidate against the RFQ. To be selectable a quote must have both amounts non-zero and the leg matching the RFQ's `baseQty` exact; and against the RFQ's price bound, on a `BUY` the quote's `takerTotal` — what the taker pays, your `makerReceives.amount` plus the taker fee charged on it — must be at or under the limit, and on a `SELL` `makerPays.amount` must be at or over it. The fee is added to what you receive rather than carved out of the limit before you price, so a `BUY` quote priced at the limit no longer conforms. A quote failing these is passed over and selection re-runs across the remaining conforming quotes. ## Tracking the outcome[​](#tracking-the-outcome "Direct link to Tracking the outcome") Every transition of one of the maker's quotes arrives as a `quoteStatus` frame carrying the maker's full view of the quote: the `MakerQuote`. The statuses, and what each means for the maker: | Status | Meaning | | -------------- | ------------------------------------------------------------------------ | | `SUBMITTED` | Accepted into the open auction and competing. | | `SELECTED` | Won. The frame carries the settlement authorization; settle it on-chain. | | `NOT_SELECTED` | A conforming quote beaten by the winner. Nothing to do. | | `EXPIRED` | Still submitted when the auction closed with no winner. Nothing to do. | | `SETTLED` | The fill was observed on-chain and the trade is done. | | `FAILED` | A `SELECTED` quote whose RFQ was later terminated without settling. | | `CANCELLED` | The maker retracted the quote before selection. | `QuoteStatus` is an open set: values may be added, so a client must tolerate one it does not recognize rather than failing to parse the frame. `PENDING_DELIVERY` and `DEFAULTED` exist on the shared enum but belong to promised-delivery settlement on other venues; they are not part of the xStocks flow, which runs `SUBMITTED → SELECTED → SETTLED`. A `SELECTED` frame: ``` { "kind": "quoteStatus", "rfqId": "rfq_0193b6f17c107d6c8000abc123456789", "quoteId": "qt_0193b6f17c107d6c8000aaa123456789", "instrumentId": "TSLAX-USDC-SPOT", "side": "BUY", "status": "SELECTED", "makerPays": { "token": "TSLAX", "amount": "1" }, "makerReceives": { "token": "USDC", "amount": "200" }, "acceptableForMs": 30000, "receivedAt": 1716284400000, "spender": "0x1111111111111111111111111111111111111111", "permitSignature": "0x…", "settlementDeadline": 1716284430 } ``` The legs name their tokens by symbol like everywhere else on the API; resolve a symbol to its contract with `GET /v1/rfq/tokens` when acting on-chain. The three settlement fields (`spender`, `permitSignature`, `settlementDeadline`) **appear only from `SELECTED` onward**, and they stay on the quote through the statuses that follow. Capture them the moment the quote reaches `SELECTED` and settle from that snapshot. * `settlementDeadline` is unix **seconds**, not milliseconds, because Permit2 signs it into its EIP-712 payload and the chain compares it to `block.timestamp`. It is the same figure the `rfq` frame published, echoed here so a maker settling from the quote alone never has to hold the RFQ. * `acceptableForMs` echoes the window the maker submitted, or is absent when the submission named none. * `spender` is your wrapper's address, bound into the Silhouette-signed authorization. It must be `msg.sender` when Permit2 is called, which means your wrapper submits the transaction; no other contract can consume the signature. Durability is the point of the channel. Each transition is captured in the transaction that commits it and delivered in per-account commit order, and `quoteStatus` replays the maker's recent quotes on subscribe, so a maker whose socket dropped re-fetches every missed outcome on reconnect, including the Permit2 authorization on a quote that reached `SELECTED` while it was disconnected. A maker never loses the settlement authorization to a transient disconnect. `GET /v1/rfq/maker/quotes` is the REST equivalent, cursor-paginated with an optional `?status=` filter, carrying the same `MakerQuote` view, permit fields included. A `SETTLED` frame carries no settlement transaction hash: the maker submitted the transaction and already holds it. The RFQ's settlement hash lives on the taker-side `rfqStatus` view's `txHash`. Settling a `SELECTED` quote (the wrapper call, the Permit2 binding, and the `Filled` event) is the [settlement page](https://docs.silhouette.exchange/rfq/market-making/xstocks/settlement.md). ## Cancelling and last look[​](#cancelling-and-last-look "Direct link to Cancelling and last look") `POST /v1/rfq/maker/quotes/{quoteId}/cancel` retracts a still-`SUBMITTED` quote before selection, and so before the maker holds any signed permit. The quote is marked `CANCELLED`, dropped from the auction, and the response carries the `CANCELLED` quote. To re-price instead of withdrawing, don't cancel: submit a fresh quote for the same RFQ and adapter, which replaces the terms in place. Last look works by omission. Silhouette never asks a maker to back out of a selected quote; a maker that chooses not to settle simply does not submit `fill()`. The RFQ then fails once the settlement deadline passes with no fill observed, the taker's locked funds are released, and the quote's final status is `FAILED`. Not submitting the fill is the entire last-look path; there is no endpoint for it. ## Publishing price ladders[​](#publishing-price-ladders "Direct link to Publishing price ladders") Indicative pricing travels on a separate, maker-only socket: `wss://rfq-api.silhouette.exchange/v1/rfq/prices/ws`. Unlike the shared stream, the HTTP upgrade request itself is authenticated, with the standard [HMAC headers](https://docs.silhouette.exchange/rfq/api.md#signing-requests) over a canonical `GET /v1/rfq/prices/ws` with an empty body, and the resolved account must be an active maker operating at least one settlement adapter, or the upgrade is rejected before the socket opens. Approval to quote a market is not enough on its own. After the socket opens, each message is a bare ladder object with no `kind` envelope, coalesced and unacknowledged. Each entry is a `[price, size]` string pair: ``` { "instrumentId": "TSLAX-USDC-SPOT", "bids": [["199", "10"], ["198.5", "25"]], "asks": [["201", "10"], ["201.5", "25"]], "ts": 1716284399750 } ``` Ladders feed the public top-of-book `prices` topic on the shared stream, aggregated across every maker pricing the instrument and attributed to none of them. This is how takers see your pricing and decide to raise an RFQ. The price-ingest socket uses native WebSocket ping/pong rather than the application-level keepalive, and a maker's ladders are cleared when its price-ingest session ends. Eligibility is re-read while the socket is open, not only at connect: a maker suspended mid-session, or left operating no settlement adapter, has its ladders purged from the book and its socket closed, so redial once you can settle again. To restate the eligibility rule from above: ladders do not gate RFQ eligibility. Pricing a market and being quotable on it are separate: the `openRfqs` subscription plus pair approval makes you quotable; ladders make your pricing visible. A serious maker does both. --- # xStocks Settlement A quote that reaches `SELECTED` carries a Silhouette-signed Permit2 authorization: the `spender`, `permitSignature`, and `settlementDeadline` fields on the quote, delivered as described on the [quoting page](https://docs.silhouette.exchange/rfq/market-making/xstocks/quoting.md). You relay that authorization on-chain by calling `fill()` on the wrapper you deployed. The wrapper consumes the authorization to pull the taker token from the omnibus, produces the maker leg (from its own inventory, or through Backed's AtomicSwap) and emits the `Filled` event Silhouette observes, all in one transaction that either completes or reverts entirely. This page specifies exactly what Silhouette signs, what the wrapper must do, and what Silhouette verifies before it credits the fill. ## What Silhouette signs[​](#what-silhouette-signs "Direct link to What Silhouette signs") For each selected quote, Silhouette signs one EIP-712 `PermitWitnessTransferFrom` under the canonical Permit2 domain: ``` EIP712Domain { name: "Permit2" chainId: 999 // illustrative: HyperEVM mainnet; confirm the value for your deployment during onboarding verifyingContract: 0x000000000022D473030F116dDEE9F6B43aC78BA3 } ``` `version` is intentionally absent; Permit2's `EIP712Domain` omits it. Permit2 forms its primary typehash by concatenating a fixed `PermitWitnessTransferFrom` stub with the wrapper's byte-exact witness type string, passed as the `witnessTypeString` argument at call time. Your wrapper must pass the same string it was compiled with, character for character; one byte of drift and the recovered signer no longer matches, so the fill reverts before anything moves. The inventory witness type string is: ``` InventoryWitness witness)InventoryWitness(address makerToken,uint256 makerAmount)TokenPermissions(address token,uint256 amount) ``` producing the full type: ``` PermitWitnessTransferFrom(TokenPermissions permitted,address spender,uint256 nonce,uint256 deadline,InventoryWitness witness)InventoryWitness(address makerToken,uint256 makerAmount)TokenPermissions(address token,uint256 amount) ``` The xChange witness type string is: ``` XchangeWitness witness)SwapMessage(bytes32 quoteId,uint256 expiration,Transfer incomingTransfer,Transfer outgoingTransfer)TokenPermissions(address token,uint256 amount)Transfer(address from,address to,address token,uint256 amount)XchangeWitness(SwapMessage swap,uint256 makerAmount) ``` producing the full type: ``` PermitWitnessTransferFrom(TokenPermissions permitted,address spender,uint256 nonce,uint256 deadline,XchangeWitness witness)SwapMessage(bytes32 quoteId,uint256 expiration,Transfer incomingTransfer,Transfer outgoingTransfer)TokenPermissions(address token,uint256 amount)Transfer(address from,address to,address token,uint256 amount)XchangeWitness(SwapMessage swap,uint256 makerAmount) ``` The witness carries the quoted maker amount alongside the swap because the swap may deliver more than the omnibus is owed. Binding it in the signature is what stops the amount being one your submitting address gets to choose. Each field of the permit is bound as follows: | Permit field | Value Silhouette signs | | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `permitted.token` | The taker token (USDC on a `BUY`; the base token on a `SELL`). | | `permitted.amount` | Exactly the quoted `makerReceives` amount, in base units. In xChange mode this is what leaves the omnibus, whatever share of it your swap routes to Backed. | | `spender` | Your wrapper contract address, the `spender` field on the `SELECTED` quote. | | `nonce` | The `quoteId` cast to `uint256`: a UUIDv7 right-aligned into 32 bytes, high 128 bits zero. | | `deadline` | Unix seconds. Inventory: the RFQ's `settlementDeadline`, echoed as the quote's `settlementDeadline` field. xChange: `swapMessage.expiration`, Backed's own value, which your wrapper rebuilds this deadline from. | | `witness` | Inventory: the EIP-712 hash of `InventoryWitness(makerToken, makerAmount)`. xChange: the EIP-712 hash of `XchangeWitness(swap, makerAmount)` — the exact Backed `SwapMessage` Silhouette validated, and the share of its outgoing leg the omnibus is owed. | The crucial mechanic: the wrapper does **not** pass `spender` to `permitWitnessTransferFrom`. Permit2 takes it from `msg.sender` and checks it against the value bound into the signature, so Silhouette's signature is usable only by the one wrapper it names; no other contract can consume it. The `nonce` doubles as the reconciliation join key: it is the quote id, and it ties the on-chain fill back to the RFQ. The `SELECTED` quote carries only the signature, the spender, and the deadline. You reconstruct the rest of the permit and the witness from the quote's own legs: the leg amounts in base units, and each leg's token symbol resolved to its ERC-20 address with `GET /v1/rfq/tokens`. ## The `Filled` event[​](#the-filled-event "Direct link to the-filled-event") Every approved wrapper emits the same `Filled` event, byte-for-byte identical; Silhouette scans this exact signature across every approved wrapper address: ``` event Filled( bytes32 indexed quoteId, // = Silhouette's quoteId (UUIDv7 zero-padded to 32 bytes) address indexed payer, // = omnibus address indexed maker, // freeform maker identity (e.g. a maker-controlled EOA) address takerToken, // USDC for a Buy address makerToken, // xStock for a Buy uint256 takerAmount, // amount of takerToken pulled from payer uint256 makerAmount // amount of makerToken delivered to payer ); ``` `quoteId` is Silhouette's quote id (the UUIDv7 zero-padded to 32 bytes, the same value encoded into the Permit2 nonce) and is the join key back to the quote. In xChange mode it is Silhouette's id, never Backed's: Backed's `SwapMessage` carries its own `quoteId` for its own replay map inside the AtomicSwap contract, and the two identifiers never mix. `payer` is the omnibus. `maker` is a maker-controlled address used for indexing only; it gates nothing. ## The inventory wrapper[​](#the-inventory-wrapper "Direct link to The inventory wrapper") ``` // SPDX-License-Identifier: MIT pragma solidity ^0.8.26; interface IInventoryWrapper { error InsufficientInventory(); error TakerDeliveryMismatch(); error MakerDeliveryMismatch(); error InvalidMaker(); error InvalidOmnibus(); error InvalidOneUnitRoundingToken(); error InvalidWithdrawalRecipient(); error UnauthorisedMaker(); error UnauthorisedPayer(); function omnibus() external view returns (address); function maker() external view returns (address); function oneUnitRoundingTokens(address token) external view returns (bool); event Filled( bytes32 indexed quoteId, address indexed payer, address indexed maker, address takerToken, address makerToken, uint256 takerAmount, uint256 makerAmount ); event Withdrawn(address indexed token, address indexed to, uint256 amount); struct InventoryWitness { address makerToken; uint256 makerAmount; } /// @param payer Omnibus address that signed the Permit2 message. /// @param takerToken Token pulled from `payer` (e.g. USDC). /// @param takerAmount Amount of `takerToken` to pull. /// @param witness Maker token and amount bound into the Permit2 witness. /// @param quoteId Silhouette's quote id; encoded into the Permit2 `nonce`. /// @param deadline Permit2 deadline (absolute unix seconds). /// @param permitSig 65-byte ECDSA from `payer` over PermitWitnessTransferFrom. function fill( address payer, address takerToken, uint256 takerAmount, InventoryWitness calldata witness, bytes32 quoteId, uint256 deadline, bytes calldata permitSig ) external; /// Transfers maker-owned inventory or accumulated proceeds out /// of the wrapper. Only the immutable maker may call. function withdraw(address token, uint256 amount, address to) external; } ``` A conforming `fill()` performs the following, atomically, in this order: 1. Require `payer` to equal the omnibus pinned by the constructor. Submission stays permissionless even so: the omnibus's Permit2 signature binds the complete maker leg, and another Permit2 owner cannot self-sign a dust payment that drains the wrapper's pre-funded inventory; its own signature would name itself as payer and fail this check. 2. Hash `InventoryWitness(makerToken, makerAmount)` and call `Permit2.permitWitnessTransferFrom(...)` with the fixed inventory witness type string above, taking the taker token from `payer` into `address(this)`. 3. Measure the wrapper's taker-token balance and require the exact `takerAmount` increase. Tokens that charge transfer fees or rebase during the call are unsupported and revert with `TakerDeliveryMismatch`. 4. Verify the wrapper's maker-token inventory is at least `witness.makerAmount`; revert `InsufficientInventory` otherwise. 5. Transfer `witness.makerAmount` to `payer` through a safe ERC-20 call that accepts a `true` return or no return data, and require the payer's balance increase to equal that amount. A maker token pinned in the wrapper's immutable one-unit-rounding set may instead deliver one base unit less (see [the one-unit rounding tolerance](#the-one-unit-rounding-tolerance)). An ordinary-token shortfall, a larger xStock shortfall, or any over-delivery reverts with `MakerDeliveryMismatch`. 6. Emit `Filled(quoteId, payer, maker, takerToken, witness.makerToken, takerAmount, witness.makerAmount)`. The wrapper delivers from its own pre-funded balance, so that balance caps the size of any single fill, and topping it up is your operational responsibility. The maker-only `withdraw(token, amount, to)` collects taker-token proceeds or rebalances inventory; it never changes the destination of a fill; it transfers only assets the wrapper already holds. ## The xChange wrapper[​](#the-xchange-wrapper "Direct link to The xChange wrapper") ``` // SPDX-License-Identifier: MIT pragma solidity ^0.8.26; import {IBackedAtomicSwap} from "./IBackedAtomicSwap.sol"; interface IXstocksXchangeWrapper { error UnauthorizedSubmitter(); error IncomingFromMismatch(); error IncomingToMismatch(); error OutgoingFromMismatch(); error OutgoingToMismatch(); error TakerDeliveryMismatch(); error MakerDeliveryMismatch(); error TakerLegAboveQuote(); error MakerLegBelowQuote(); error SurplusRequiresWrapperDelivery(); error RoundingTokenRequiresSurplus(); error InvalidWithdrawalRecipient(); error ReentrantCall(); error InvalidOneUnitRoundingToken(); /// @notice The amounts Silhouette quoted. The swap message does not /// determine them: `takerAmount` is what leaves the omnibus and /// `makerAmount` is what returns to it. You keep the difference /// on either leg. struct QuotedLegs { uint256 takerAmount; uint256 makerAmount; } function oneUnitRoundingTokens(address token) external view returns (bool); /// @return Backed's account, fixed at deployment. Both legs of every /// accepted `SwapMessage` must name it, and it must equal the /// Backed transfer address registered for this maker with /// Silhouette. function xstocksTransferAddress() external view returns (address); event Filled( bytes32 indexed quoteId, address indexed payer, address indexed maker, address takerToken, address makerToken, uint256 takerAmount, uint256 makerAmount ); event Withdrawn(address indexed token, address indexed to, uint256 amount); /// @param omnibus Omnibus address that signed the Permit2 message. /// @param silhouetteQuoteId Silhouette quote id encoded into the Permit2 /// nonce. Distinct from the xStocks swap quote id. /// @param xstocksSwapParams Backed-signed xStocks `SwapMessage`. /// @param quoted The amounts Silhouette quoted. Any other pair /// fails Permit2 signature verification. /// @param xstocksSignature Backed's EIP-712 signature over the xStocks swap. /// @param omnibusPermitSignature Omnibus signature over PermitWitnessTransferFrom. function fill( address omnibus, bytes32 silhouetteQuoteId, IBackedAtomicSwap.SwapMessage calldata xstocksSwapParams, QuotedLegs calldata quoted, bytes calldata xstocksSignature, bytes calldata omnibusPermitSignature ) external; /// @notice Collect a retained spread. Maker-only; the zero recipient is /// refused. function withdraw(address token, uint256 amount, address to) external; } ``` A conforming `fill()` performs the following, atomically, in this order: 1. Permit only the configured maker submitter, and reject reentrant calls. 2. Require the four party bindings: `incomingTransfer.from == address(this)`, `incomingTransfer.to == xstocksTransferAddress`, `outgoingTransfer.from == xstocksTransferAddress`, and `outgoingTransfer.to` to be either `omnibus` or `address(this)`. Then require the two amount bounds: `incomingTransfer.amount <= quoted.takerAmount` and `outgoingTransfer.amount >= quoted.makerAmount`. Where the outgoing leg exceeds the quote, require `outgoingTransfer.to == address(this)`; the omnibus is owed the quote and no more, so a surplus it received would fail reconciliation. A maker token in the immutable one-unit-rounding set routed through the wrapper must carry a surplus, which is what covers the base unit each of the two share conversions can round away. 3. Hash `XchangeWitness(SwapMessage swap,uint256 makerAmount)` — the complete `SwapMessage` struct hash and the omnibus's share — and call `Permit2.permitWitnessTransferFrom(...)` with `permitted.token = swap.incomingTransfer.token`, `permitted.amount = quoted.takerAmount`, `nonce = uint256(silhouetteQuoteId)`, and `deadline = swap.expiration`, pulling the taker token from `omnibus` into `address(this)`. 4. Record the Backed transfer account's taker-token balance and the payer's maker-token balance. Set the AtomicSwap allowance safely to the exact incoming amount, including a zero-first fallback for tokens that require it. 5. Call `atomicSwap.executeSwap(swap, signature, emptyPermit)`, then reset the allowance to zero. 6. Require the Backed transfer account's taker-token balance to have increased by exactly `incomingTransfer.amount`. If the maker token was delivered to the wrapper, forward `quoted.makerAmount` to `omnibus` through an optional-return safe transfer, keeping the rest. Require the omnibus's maker-token balance increase to equal `quoted.makerAmount`, or one base unit less for a maker token pinned in the one-unit-rounding set. An ordinary-token shortfall, a larger xStock shortfall, or any over-delivery to the omnibus reverts. 7. Emit `Filled(silhouetteQuoteId, omnibus, maker, swap.incomingTransfer.token, swap.outgoingTransfer.token, quoted.takerAmount, quoted.makerAmount)` — what the omnibus paid and received, not what passed through Backed. Whatever you retain stays in the wrapper until you call `withdraw(token, amount, to)`. Settlement never leaves the omnibus's own funds behind, so that path reaches only what you earned. An xChange settlement transaction must invoke exactly one successful `fill()`. Batching several fills in one transaction is invalid even when every `Filled` event has the canonical shape, because Silhouette reconciles the transaction receipt's net omnibus movements against one winning quote; a receipt carrying two fills' movements matches neither. ## The Permit2 and Backed interfaces[​](#the-permit2-and-backed-interfaces "Direct link to The Permit2 and Backed interfaces") Your wrapper calls two external contracts. Permit2's signature-transfer entrypoint: ``` // Canonical Uniswap Permit2 deployment, identical on every EVM chain. // Address on HyperEVM: 0x000000000022D473030F116dDEE9F6B43aC78BA3 interface ISignatureTransfer { struct TokenPermissions { address token; uint256 amount; } struct PermitTransferFrom { TokenPermissions permitted; uint256 nonce; uint256 deadline; } struct SignatureTransferDetails { address to; uint256 requestedAmount; } function permitWitnessTransferFrom( PermitTransferFrom memory permit, SignatureTransferDetails calldata transferDetails, address owner, bytes32 witness, string calldata witnessTypeString, bytes calldata signature ) external; } ``` And Backed's AtomicSwap, xChange mode only. Note the `Transfer` field order, `(from, to, token, amount)`, and that `executeSwap` takes three arguments; the wrapper passes an empty `Permit`: ``` interface IBackedAtomicSwap { struct Transfer { address from; address to; address token; uint256 amount; } struct SwapMessage { bytes32 quoteId; // Backed's own per-quote id (distinct from Silhouette's quoteId) uint256 expiration; // unix seconds; at or before the RFQ's settlementDeadline Transfer incomingTransfer; Transfer outgoingTransfer; } struct Permit { address owner; uint256 deadline; uint8 v; bytes32 r; bytes32 s; } function executeSwap( SwapMessage calldata swap, bytes calldata signature, Permit calldata permit ) external; } ``` Backed signs the `SwapMessage` under this EIP-712 domain, with the AtomicSwap deployment as the verifying contract (its address is supplied during onboarding): ``` EIP712Domain { name: "AtomicSwap" version: "1" chainId: 999 // illustrative; confirm during onboarding verifyingContract: } ``` The typehashes are: ``` SwapMessage(bytes32 quoteId,uint256 expiration,Transfer incomingTransfer,Transfer outgoingTransfer)Transfer(address from,address to,address token,uint256 amount) Transfer(address from,address to,address token,uint256 amount) ``` ### What Silhouette validates before signing[​](#what-silhouette-validates-before-signing "Direct link to What Silhouette validates before signing") Before signing its Permit2 over an xChange quote's `SwapMessage`, Silhouette validates each of the following off-chain: * The Backed signature recovers to the signer registered for you at onboarding. * `incomingTransfer.from` is your wrapper. * `incomingTransfer.to` and `outgoingTransfer.from` are the registered Backed transfer address. * `incomingTransfer.token` is the RFQ's taker token, and `incomingTransfer.amount` is **at most** the quoted taker amount in base units. * `outgoingTransfer.token` is the RFQ's maker token, and `outgoingTransfer.amount` is **at least** the quoted maker amount in base units. * `outgoingTransfer.to` is the omnibus or your wrapper, and must be your wrapper wherever the outgoing leg exceeds the quote. * `expiration` is still in the future and at or before the RFQ's `settlementDeadline`. Backed's value is adopted rather than replaced: Silhouette signs its Permit2 with it, because the wrapper rebuilds its own deadline from the same field. One distinction matters more than the rest: **the Backed transfer address is Backed's own account and is the counterparty on both legs; the AtomicSwap address is the EIP-712 verifying contract and is never a transfer party.** They are separate values, and neither leg is ever compared with the AtomicSwap address. Binding both legs to a registered address (rather than only requiring that they agree with each other) is what stops a Backed-signed message from routing the swap through an account the maker chose. Your wrapper enforces the same binding on-chain against its own `xstocksTransferAddress` immutable, so a mismatch would revert; refusing it at validation means Silhouette never signs a permit whose settlement cannot complete. If any check fails, Silhouette refuses to sign and the quote is not selected. It ends `NOT_SELECTED` if a conforming quote wins the auction, or `EXPIRED` if the auction closes with no winner. ## The one-unit rounding tolerance[​](#the-one-unit-rounding-tolerance "Direct link to The one-unit rounding tolerance") xStocks store balances as shares, and `balanceOf` is `floor(shares × multiplier() ÷ 1e18)`. Once a token's multiplier is above `1e18`, a transfer can credit one base unit less than the amount sent. A wrapper therefore pins the exact xStock addresses for which it accepts a delivery one base unit short of the nominal amount. The tolerance never permits zero delivery. Stablecoins and other ordinary tokens are never in that set: any shortfall for them, a larger xStock shortfall, or a delivery to the omnibus above what it is owed reverts. A surplus you keep in xChange mode is not such a delivery — it stays in your wrapper and never reaches the omnibus. Silhouette applies the same token-specific tolerance when it reconciles the receipt, reading the policy from the winning wrapper, so the tolerance enforced on-chain and the tolerance applied at reconciliation cannot diverge, and reconciliation is not weakened for ordinary tokens. The tolerance has a routing consequence in xChange mode. Routing a pinned token through your wrapper means two share conversions rather than one, so Backed must deliver more than the quoted amount: without a surplus the wrapper could not forward the nominal amount it owes the omnibus, and the call reverts with `RoundingTokenRequiresSurplus`. Deliver a pinned token straight to the omnibus whenever you are not taking your spread on that leg. The Backed xStock deployment is rebasing, not fee-on-transfer. ### Pin every xStock you quote[​](#pin-every-xstock-you-quote "Direct link to Pin every xStock you quote") Each xStock's multiplier starts at exactly `1e18`, where a transfer credits the full amount sent. Backed changes it by queuing a new value in `newMultiplier()`, with the Unix time it applies from in `newMultiplierActivationTime()`. At that time `multiplier()` returns the new value, without a transaction or an event. From then on, a wrapper that has not pinned the token reverts any fill whose delivery rounds down. Pin every xStock you quote, including any whose multiplier is still exactly `1e18`. If you pin only the tokens whose multiplier has already changed, the first sign of the next change is a reverted fill. If your wrapper fixes the set at deployment, as the reference wrappers do, pass every xStock you will quote to its constructor. Deploy a new wrapper before you quote a token that Backed lists later. If your wrapper can change the set after deployment, add each xStock before you first quote it. Pinning a token whose multiplier is still `1e18` does not change how inventory-mode fills settle. In xChange mode, the surplus rule above applies to the token whenever you route it through your wrapper. To check a token, read `multiplier()`, `newMultiplier()`, and `newMultiplierActivationTime()` on the token, and `oneUnitRoundingTokens(token)` on your wrapper. ## Settlement confirmation[​](#settlement-confirmation "Direct link to Settlement confirmation") Silhouette observes the `Filled` event, requires the `payer` to equal the configured omnibus and the emitting contract to equal the wrapper captured on the winning quote, then derives the omnibus's net taker-token outflow and maker-token inflow from the transaction **receipt** (rather than trusting the `Filled` amounts) and only then credits the fill. The taker-token outflow must equal the quote; the maker-token inflow must too, subject to the one-unit tolerance above. The quote then reads `SETTLED`. ## Deploying[​](#deploying "Direct link to Deploying") The wrappers target Solidity `^0.8.26`. Everything the wrapper trusts is a constructor immutable and cannot change after deployment: a new maker identity, omnibus, Permit2 address, AtomicSwap address, Backed transfer address, or one-unit-rounding token set means a fresh deployment. `fill()` is deliberately permissionless on the inventory wrapper. Its safety comes from the Permit2 signature and the pinned omnibus, not from a caller allowlist. You may extend a reference wrapper, with metrics or a submitter allowlist, provided the `Filled` event shape stays byte-for-byte identical, the legs stay atomic, and the inventory wrapper retains its immutable omnibus and maker checks. The authorization, reentrancy, counterparty, allowance, and balance-delta requirements remain mandatory. Compile with `evm_version = "paris"`. HyperEVM does not support `PUSH0`, so a post-Shanghai target produces bytecode that cannot run. Verify the deployed bytecode on the block explorer. Review is mandatory and gating: Silhouette reviews the wrapper source before mainnet deployment and pins the approved deployed code hash, so a wrapper with no approved pin is refused, and repointing a registered wrapper at unapproved code cannot bypass the check. A wrapper settles only once its source is approved and its deployed bytecode confirmed to match, whether you deploy a reference implementation unchanged or write your own. Silhouette shares reference implementations of both wrappers, the Permit2 and Backed interfaces, and a deployment script during onboarding. --- # How RFQs Work Building on RFQ? This page explains the concepts. For endpoints, request fields, responses, and schemas, see the [RFQ API](https://docs.silhouette.exchange/rfq/api.md) overview and the interactive [API Reference](https://docs.silhouette.exchange/rfq/api/reference.md). An RFQ, or request for quote, is a trading workflow where a taker asks makers for executable prices on a specific instrument. The system is designed to work across HyperEVM and HyperCore, giving traders one universal flow to execute against all the available instruments on Hyperliquid. The flow is built to span instruments such as: * Tokenized instruments issued on EVM * Larger perp positions on HyperCore or through HIP-3 deployers * Spot instruments on HyperCore or HyperEVM ## Main actors[​](#main-actors "Direct link to Main actors") ### Takers[​](#takers "Direct link to Takers") The taker is the account requesting liquidity. A taker creates the RFQ, reviews quotes when using manual acceptance, accepts a quote or waits for auto-selection, and tracks the final trade state. A taker can hold funds on either HyperCore or HyperEVM. Settlement abstracts away which chain the funds are on and returns funds to the same chain the taker initiated from. ### Makers[​](#makers "Direct link to Makers") The maker is the market maker that prices an instrument and fills the trade. A maker watches for open RFQs on supported instruments and submits quotes. As with takers, maker funds are abstracted away from the chain: the maker responds to an RFQ and settlement handles the chain abstraction. Makers gain capital efficiency from how settlement is authorized. A maker declares how each quote settles through its settlement mode: from its own inventory, through an external venue with the adapter's payload attached to the quote, or as a promised delivery owed within a bounded window (see [`createMakerQuote`](https://docs.silhouette.exchange/rfq/api/reference.md)). Each quote carries an expiry, and the engine binds that expiry to an on-chain [Permit2](https://github.com/Uniswap/permit2) deadline, so a maker commits to deliver the tokens only within a bounded window. The objective is to let makers quote more competitively without parking idle inventory. ### Silhouette[​](#silhouette "Direct link to Silhouette") Silhouette is the coordinator that sits between takers and makers and runs the RFQ lifecycle. It coordinates the taker's request, collects maker quotes, selects or records an accepted quote, locks and releases balances as needed, exposes the final trade status, and uses the CoreWriter contracts to manage cross-chain transfers. Takers and makers never interact directly; every step passes through Silhouette. ## Instruments[​](#instruments "Direct link to Instruments") Each RFQ is for one instrument, such as `TSLAX-USDC-SPOT`. The canonical instrument ID has the form `BASE-QUOTE-TYPE` and identifies the base token, the quote token, and the product type (for example `SPOT`). See the `InstrumentId` schema in the [API Reference](https://docs.silhouette.exchange/rfq/api/reference.md) for the exact format. The `TYPE` segment is what lets the same flow generalise: the contract defines `SPOT` and `PERP` instrument types, and settlement spans tokenized instruments on EVM as well as HyperCore spot and perp venues. Expect the supported instrument set to grow rather than the workflow to change. The taker sends a `side`: * `BUY` means the taker wants to buy the base token and is setting the maximum quote amount they will pay. * `SELL` means the taker wants to sell the base token and is setting the minimum quote amount they will accept. The taker also sends `baseQty`, the amount of the base token to trade, and `quoteLimit`, the taker's price bound in the quote token. A quote outside the bound cannot win, and the bound is never shown to makers. The bound is required in both acceptance modes, because it sizes the funds locked at submission. On a spot instrument `baseQty` must land on a step: a multiple of the `baseQtyIncrement` the instruments endpoint publishes for the pair. A size off the step is refused with `BASE_QTY_OFF_INCREMENT`, and `details.increment` names the step to round to. ### Locked funds[​](#locked-funds "Direct link to Locked funds") Submission locks the taker's worst-case pay side, in either acceptance mode: `quoteLimit` on a `BUY`, `baseQty` on a `SELL`. A request the balance cannot cover is rejected rather than queued. A perp request locks nothing, because the margin sits at the venue. ### Minimum order value[​](#minimum-order-value "Direct link to Minimum order value") A market can set a smallest order value it takes, in the quote token. Read it as `minQuoteNotional` on the instrument from `GET /v1/rfq/instruments`. A market that sets no minimum omits the field and takes any size its tokens can represent, which is how every market ships until an operator tightens it. On a `BUY` the minimum is measured against `quoteLimit` net of the taker fee: the limit has to cover `minQuoteNotional` **plus** the fee charged on it. A `SELL` is not measured, because what it is worth is only known once a maker prices it. A request under the minimum is rejected at submission with `BELOW_MIN_NOTIONAL`, and `details.minQuoteNotional` in that response carries the figure, so the next request is sized from the rejection rather than from a guess. The same code can arrive later as a `failureCode`, if the floor rises while a request sits `PENDING`. Read the field rather than hard-coding a number: it is set per market and can change. ## Quote window[​](#quote-window "Direct link to Quote window") Every RFQ has a quote window. During this window, makers can submit competing quotes. A short window favors faster execution. A longer window gives more makers time to respond and can improve price discovery. If the taker omits `windowMs`, Silhouette uses the operator's default window. A supplied value is clamped server-side to the operator's minimum and maximum, so an out-of-range request is honoured at the nearer bound rather than rejected, and the submission response returns the deadline the clamp settled on. ## Auto-acceptance (two-round flow)[​](#auto-acceptance-two-round-flow "Direct link to Auto-acceptance (two-round flow)") In the two-round flow the taker submits and makers quote, with no acceptance step required. The taker submits an RFQ with `autoAccept: true`, Silhouette waits until the quote window closes, then automatically selects the best conforming quote. Selection acts on the taker's behalf and works to the `quoteLimit` the request carries. The taker keeps the option to accept early. Calling [`acceptRfqQuote`](https://docs.silhouette.exchange/rfq/api/reference.md) on an auto-accept RFQ takes the quote immediately rather than waiting for the window to close, so the auction end is a backstop rather than the only moment a quote can win. Perp instruments cannot auto-accept. Matched execution needs the taker's signed order at acceptance, so `autoAccept: true` on a perp instrument is rejected. If there is no conforming quote by the deadline, the RFQ ends `FAILED` and locked funds are released. Auto-acceptance is useful when the taker wants the best available quote at the end of the window without a second decision step. ## Manual acceptance (three-round flow)[​](#manual-acceptance-three-round-flow "Direct link to Manual acceptance (three-round flow)") The three-round flow adds a third round, where the taker reads the quotes and accepts one, in exchange for control over which quote wins. The taker submits an RFQ with `autoAccept: false` (or omits `autoAccept`, the default). The RFQ enters `PENDING` while makers submit quotes. The taker reads the competing quotes with [`listRfqRequestQuotes`](https://docs.silhouette.exchange/rfq/api/reference.md) and explicitly accepts one with [`acceptRfqQuote`](https://docs.silhouette.exchange/rfq/api/reference.md) before the auction ends. Here acceptance is the only way the request fills: nothing is selected on the taker's behalf when the window closes. After acceptance, the RFQ moves toward settlement. If settlement succeeds, the RFQ becomes `SETTLED`. If the selected maker does not deliver or settlement cannot complete, the RFQ becomes `FAILED` and locked funds are released. Manual acceptance is useful when the taker wants to inspect quotes before committing. Rate limits apply to this flow to discourage spam. ## Maker quoting[​](#maker-quoting "Direct link to Maker quoting") Makers discover open RFQs through [`listMakerRequests`](https://docs.silhouette.exchange/rfq/api/reference.md), which returns the open RFQs on the instruments the maker is approved to quote, or by subscribing to the `openRfqs` topic. Either route needs an active maker record, approval for the instrument's pair, and at least one operated settlement adapter. A maker submits a quote with [`createMakerQuote`](https://docs.silhouette.exchange/rfq/api/reference.md). A quote describes what the maker pays and what the maker receives. Quotes start as `SUBMITTED`. Before selection, a maker can cancel a still-submitted quote with [`cancelMakerQuote`](https://docs.silhouette.exchange/rfq/api/reference.md), taking it to `CANCELLED`; to re-price, the maker submits a fresh quote for the same RFQ. Selection marks one quote `SELECTED` and the rest `NOT_SELECTED` (or `EXPIRED` if the window closes with no conforming quote). It runs when the auction ends, or earlier if the taker accepts a quote before then, which it may do in either selection mode. After selection, the winning quote follows its settlement mode: one that settles atomically goes straight to `SETTLED`; one whose settlement does not complete ends `FAILED`. A winning promised quote moves to `PENDING_DELIVERY` while the maker owes the on-chain delivery, then to `SETTLED` on delivery or `DEFAULTED` when the maker misses its window. `DEFAULTED` is distinct from `FAILED` because it is attributable to the maker and carries consequences. When a quote is selected, the maker reads it back through [`listMakerQuotes`](https://docs.silhouette.exchange/rfq/api/reference.md). A `SELECTED` quote carries the engine-signed Permit2 authorization the maker relays on-chain to settle. ## Trade lifecycle[​](#trade-lifecycle "Direct link to Trade lifecycle") Process step Active / settled Cancelled / failed Each branch resolves to one of the lifecycle states below. The two unsettled terminals divide on whether the trade was called off deliberately: a taker cancelling its own request, which it may do while the request is `PENDING` and before its `auctionEndsAt`, ends `CANCELLED`, and every other ending without a settlement ends `FAILED`, with `failureReason` carrying which one it was. Status values are returned in `SCREAMING_SNAKE_CASE`; the set is open, so treat an unrecognised value as non-terminal. See the `RfqStatus` schema in the [API Reference](https://docs.silhouette.exchange/rfq/api/reference.md) for the authoritative list. | Status | Meaning | Terminal | | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | | `PENDING` | Auction open; quotes may be arriving. | No | | `QUOTED` | A winning quote was selected or accepted and carries a settlement artefact to observe (a signed Permit2 permit or an on-chain escrow); settlement is in progress. A quote whose settlement mode settles atomically skips this state and goes straight to `SETTLED`. | No | | `PENDING_DELIVERY` | The winning quote is a promised delivery: the maker owes the on-chain delivery within its window. | No | | `SETTLED` | Settled on-chain; a completed trade carrying a settlement transaction hash. | Yes | | `FAILED` | Every ending without a settlement that nobody called off: no quotes arrived, none conformed, none was accepted before the auction ended, the settlement deadline passed with no fill, or a delivery window was exhausted. Locked funds are released. | Yes | | `CANCELLED` | A party ended the request deliberately before settlement. In this version that means the taker cancelling its own request, while it is `PENDING` and before its `auctionEndsAt`. Once the auction closes the outcome is fixed and a cancel is refused `409`. Locked funds are released. | Yes | ## Balances and reconciliation[​](#balances-and-reconciliation "Direct link to Balances and reconciliation") The RFQ surface exposes balances and a ledger so integrators can reconcile account state. Balances are reported per token and per custody rail: a token held on both `HYPEREVM` and `HYPERCORE` has two lines. Each line carries `available`, `locked`, and `pending`, which together make up the account's claim on that rail, plus `withdrawable`, the ceiling on a single withdrawal from it. The ledger is an append-only audit trail for balance changes such as deposits, settlements, withdrawals, and adjustments. See the balance endpoints in the [API Reference](https://docs.silhouette.exchange/rfq/api/reference.md). Deposits and withdrawals are separate funding operations. Withdrawals are asynchronous and use the account's registered address; the caller cannot specify a destination. A withdrawal may name the `rail` to pay from, and is then paid from that rail or refused; omit it and a rail that can cover the amount is chosen. Funds never move between rails. See the funding endpoints in the [API Reference](https://docs.silhouette.exchange/rfq/api/reference.md). A withdrawal reports a `txHash` identifying the payout on whichever rail paid, and what the hash proves differs by rail. A `HYPEREVM` payout reports its ERC-20 transaction hash, set once the transaction is broadcast, so it records the attempt rather than proving the funds arrived; `status` is what confirms that. A `HYPERCORE` payout reports the ledger entry that moved the funds, set only on completion, so its presence is the proof. The two are separate chains with separate explorers, so read `rail` before building a link. ## Developer reference[​](#developer-reference "Direct link to Developer reference") For exact endpoints, request fields, responses, and schema definitions, start at the [RFQ API](https://docs.silhouette.exchange/rfq/api.md) overview and explore the interactive [API Reference](https://docs.silhouette.exchange/rfq/api/reference.md). Authentication is covered in the [RFQ API authentication](https://docs.silhouette.exchange/rfq/api.md#authentication) section. --- # Fees ## How much does Silhouette cost?[​](#how-much-does-silhouette-cost "Direct link to How much does Silhouette cost?") Silhouette offers two trading modes with different fee structures: * **Shielded** - Private trading executed inside Silhouette's Trusted Execution Environment (TEE). Your transactions are not publicly visible onchain. Fees are calculated dynamically - Silhouette passes 95% of its HL fee saving directly to you. * **Naked** - Open, transparent trading through Silhouette's interface. Your transactions are visible on Hyperliquid like any standard trade. Silhouette applies a small fee via Hyperliquid's [builder code](https://hyperliquid.gitbook.io/hyperliquid-docs/trading/builder-codes) system - a protocol-native mechanism that allows frontends built on Hyperliquid to charge a fee on fills. Naked fees are the same for all users as shown in the fee schedule below. ## Shielded Trading Fees (Spot Only)[​](#shielded-trading-fees-spot-only "Direct link to Shielded Trading Fees (Spot Only)") info Shielded trading is currently available for **spot markets only**. Perps and RFQs in shielded mode are coming soon. ### How Shielded Fees Are Calculated[​](#how-shielded-fees-are-calculated "Direct link to How Shielded Fees Are Calculated") When you trade shielded, your orders are executed inside Silhouette's TEE and routed through the **Silhouette wallet** on Hyperliquid, which has **100k HYPE staked (Platinum tier, 30% HL fee discount)**. Because of that staking discount, the wallet pays a lower effective HL fee rate than an individual trader without HYPE staked. **Silhouette passes 95% of that fee saving directly to you.** There is no builder code fee in shielded mode. Your shielded fee is calculated dynamically based on the difference between your own HL rate and the Silhouette wallet's HL rate: 1. We look up **your HL fee rate** (your 14-day rolling volume tier + any HYPE staking discount on your own wallet) 2. We compare it to **the Silhouette wallet's HL fee rate** (its volume tier + Platinum staking discount) 3. The **spread** (difference) between the two is your potential saving 4. You receive **95% of that spread** as a fee discount - Silhouette retains 5% ### How It Works in Practice[​](#how-it-works-in-practice "Direct link to How It Works in Practice") * **No builder code fee in shielded mode** - Silhouette's 5% of the spread is the only markup. There is no separate builder code fee. * **Fee cap** - your shielded fee will not exceed your individual HL fee rate. If your personal HL rate matches or beats the Silhouette wallet's rate, you pay your standard HL rate. * **Savings improve over time** - as Silhouette's aggregate volume grows and unlocks better HL volume tiers, the spread widens and all shielded users benefit automatically. ### What You Pay Today[​](#what-you-pay-today "Direct link to What You Pay Today") For a user at HL Tier 0 (base) trading shielded: | | HL Direct | Shielded | You Save | | -------------- | --------- | --------- | -------- | | **Spot Taker** | 0.070% | \~0.0500% | \~28.5% | | **Spot Maker** | 0.040% | \~0.0286% | \~28.5% | The spread between your rate and Silhouette's rate is where your saving comes from. The larger the gap, the more you save. *Actual savings depend on Silhouette's current HL volume tier and HYPE staking tier. The Silhouette wallet is staked at Platinum (>100k HYPE) for a 30% baseline discount on its HL fees. As aggregate volume grows and unlocks better HL volume tiers, the spread widens and all shielded users benefit automatically.* ## Hyperliquid Fee Tiers (Reference)[​](#hyperliquid-fee-tiers-reference "Direct link to Hyperliquid Fee Tiers (Reference)") These are the underlying Hyperliquid rates used to calculate both naked base fees and shielded savings. HL tiers are based on your **14-day rolling volume** (spot volume counts double). ### Perps[​](#perps "Direct link to Perps") | Tier | 14d Volume | Taker | Maker | | ---- | ---------- | ------ | ------ | | 0 | Base | 0.045% | 0.015% | | 1 | >$5M | 0.040% | 0.012% | | 2 | >$25M | 0.035% | 0.008% | | 3 | >$100M | 0.030% | 0.004% | | 4 | >$500M | 0.028% | 0.000% | | 5 | >$2B | 0.026% | 0.000% | | 6 | >$7B | 0.024% | 0.000% | ### Spot[​](#spot "Direct link to Spot") | Tier | 14d Volume | Taker | Maker | | ---- | ---------- | ------ | ------ | | 0 | Base | 0.070% | 0.040% | | 1 | >$5M | 0.060% | 0.030% | | 2 | >$25M | 0.050% | 0.020% | | 3 | >$100M | 0.040% | 0.010% | | 4 | >$500M | 0.035% | 0.000% | | 5 | >$2B | 0.030% | 0.000% | | 6 | >$7B | 0.025% | 0.000% | ### HYPE Staking Discounts[​](#hype-staking-discounts "Direct link to HYPE Staking Discounts") These discounts are applied on top of volume tiers: | Tier | HYPE Staked | Fee Discount | | -------- | ----------- | ------------ | | Wood | >10 | 5% | | Bronze | >100 | 10% | | Silver | >1,000 | 15% | | Gold | >10,000 | 20% | | Platinum | >100,000 | 30% | | Diamond | >500,000 | 40% | ## Naked Trading Fees[​](#naked-trading-fees "Direct link to Naked Trading Fees") Silhouette charges a small builder code fee on top of Hyperliquid's standard trading fees. **Your total cost = Hyperliquid's base fee (based on your HL volume tier and HYPE staking) + the Silhouette builder code fee below.** ### Silhouette Fixed Builder Code Fee[​](#silhouette-fixed-builder-code-fee "Direct link to Silhouette Fixed Builder Code Fee") | Tier | Spot | Perps | | --------- | ------- | ------- | | All Tiers | 0.0600% | 0.0150% | These are fixed rates applied uniformly, no per-user dynamic calculation. Your Hyperliquid volume tier, HYPE staking discounts, and any other Hyperliquid-native fee reductions still apply to the base portion of your fee. See the [Hyperliquid fee tiers](#hyperliquid-fee-tiers-reference) reference above for the underlying rates. ## No Deposit or Withdrawal Fees[​](#no-deposit-or-withdrawal-fees "Direct link to No Deposit or Withdrawal Fees") Silhouette does not charge fees on deposits or withdrawals. Standard Hyperliquid gas fees apply for onchain transactions. ## Referral Discounts[​](#referral-discounts "Direct link to Referral Discounts") Silhouette's referral program provides additional fee savings. --- # Naked Trading Naked trading on Silhouette routes your orders directly to Hyperliquid via [Builder Codes](https://hyperliquid.gitbook.io/hyperliquid-docs/trading/builder-codes). Your trades are fully visible on the public ledger - the same experience as any other Hyperliquid frontend. ## How It Works[​](#how-it-works "Direct link to How It Works") When you select naked mode, your order bypasses Silhouette's [shielded execution](https://docs.silhouette.exchange/trading/shielded-trading.md) environment and goes straight to Hyperliquid's order book. Your wallet address, order size, and intent are all visible onchain. Both **spot** and **perpetuals** markets are supported in naked mode. ## When to Trade Naked[​](#when-to-trade-naked "Direct link to When to Trade Naked") Public visibility is appropriate in several cases: * **Public signalling.** A visible buy or sell communicates intent onchain and can be used deliberately as a signal. * **Perpetuals.** Shielded perpetuals are not yet available. Naked mode supports Hyperliquid's full perpetuals market today. * **Small orders.** Orders that do not require confidentiality can be routed directly to Hyperliquid without the TEE execution path. * **Public track record.** Trades routed in naked mode are recorded onchain and attributable to the user's wallet, producing a verifiable trading history. ## Supported Markets[​](#supported-markets "Direct link to Supported Markets") Naked mode routes directly to Hyperliquid via Builder Codes. You have access to the full Hyperliquid market set - every spot pair and perpetual contract available on Hyperliquid is tradeable through Silhouette in naked mode. * **Spot**: All [spot pairs](https://app.hyperliquid.xyz/trade) listed on Hyperliquid * **Perpetuals**: All 100+ [perpetual contracts](https://app.hyperliquid.xyz/trade) listed on Hyperliquid Markets update automatically as Hyperliquid adds new listings. ## Order Types[​](#order-types "Direct link to Order Types") ### Market Orders[​](#market-orders "Direct link to Market Orders") A market order requests immediate execution at the best available price. Your order routes directly to Hyperliquid's order book. ![Naked spot market buy order](/img/app-screenshots/naked_SpotMarketOrder_BUY.png) Spot market order ![Naked perpetuals market long order](/img/app-screenshots/naked_PerpsMarket_LONG.png) Perps market order ### Limit Orders[​](#limit-orders "Direct link to Limit Orders") A limit order executes at your specified price or better. You set the asset, the size, and the price you are willing to pay or receive. Limit orders rest on the book until filled or cancelled. ![Naked spot limit buy order](/img/app-screenshots/naked_SpotLimitOrder_BUY.png) Spot limit order ![Naked perpetuals limit long order](/img/app-screenshots/naked_PerpsLimit_LONG.png) Perps limit order ### Advanced Order Types[​](#advanced-order-types "Direct link to Advanced Order Types") #### TWAP (Time-Weighted Average Price)[​](#twap-time-weighted-average-price "Direct link to TWAP (Time-Weighted Average Price)") Break a large order into smaller suborders executed over a configured duration. In naked mode, each suborder is visible onchain as it executes. ![Naked spot TWAP buy order](/img/app-screenshots/naked_SpotTWAP_BUY.png) Spot TWAP order ![Naked perpetuals TWAP long order](/img/app-screenshots/naked_PerpsTWAP_LONG.png) Perps TWAP order #### Scale Orders[​](#scale-orders "Direct link to Scale Orders") Distribute an order across a configured price range. The distribution across the range is adjustable, supporting laddered entries and exits. ![Naked spot scale buy order](/img/app-screenshots/naked_SpotSCALE_BUY.png) Spot scale order ![Naked perpetuals scale long order](/img/app-screenshots/naked_PerpsSCALE_LONG.png) Perps scale order ## Naked vs Shielded[​](#naked-vs-shielded "Direct link to Naked vs Shielded") Mode is selected per trade. A [shielded spot order](https://docs.silhouette.exchange/trading/shielded-trading.md) can be placed in the same session as a naked perps order. Shielded is appropriate when a trade requires confidentiality; naked is appropriate otherwise. To understand the full flow of how orders move through the system, see [Order Lifecycle](https://docs.silhouette.exchange/trading/order-lifecycle.md). For fee details, see [Fees](https://docs.silhouette.exchange/trading/fees.md). --- # Order Lifecycle This page walks through the complete lifecycle of an order on Silhouette, from the moment you submit it to final settlement on Hyperliquid. ## Shielded Order Lifecycle[​](#shielded-order-lifecycle "Direct link to Shielded Order Lifecycle") ### 1. Submission[​](#1-submission "Direct link to 1. Submission") You place an order through the Silhouette UI in shielded mode - selecting your asset, size, and order type. The order is submitted to Silhouette's Trusted Execution Environment (TEE). At this point, no order information has been written to the public ledger. Hyperliquid has no native market-order primitive. A "market" order in the UI is a limit order with a slippage-derived price cap and an IoC (Immediate or Cancel) time-in-force. A shielded market order submits as a delegated IoC; a shielded limit order rests as a delegated GTC order until filled or cancelled. ### 2. Processing[​](#2-processing "Direct link to 2. Processing") Inside the TEE, your order is validated and queued for execution. The TEE processes orders from all users in the same secure environment. Data inside the enclave is inaccessible to anyone, including the Silhouette team. ### 3. Execution[​](#3-execution "Direct link to 3. Execution") The TEE submits your order to Hyperliquid's order book through a delegated wallet. The order is placed as an IoC (Immediate or Cancel) limit order: * If the order can be filled at the specified price or better, it fills immediately * If it cannot be filled in full, the remainder cancels - nothing rests on the public book from shielded trades The delegated wallet aggregates activity from multiple users. The market sees the trade but cannot attribute it to any individual. ### 4. Balance Update[​](#4-balance-update "Direct link to 4. Balance Update") After execution, the TEE updates your shielded balance. The update reflects your new position - the asset you bought or sold, and the resulting balance. Your shielded balance sits inside the TEE and is not readable by anyone, including Silhouette. ### 5. Settlement Complete[​](#5-settlement-complete "Direct link to 5. Settlement Complete") Your trade is now settled on Hyperliquid's order book. Your balance is updated inside the Silhouette TEE. The trade is final. From the public ledger's perspective, the settled transaction is a fill from a delegated wallet on Hyperliquid. The fill itself is visible, but it is not attributable to an individual user, strategy, or account balance. ## Naked Order Lifecycle[​](#naked-order-lifecycle "Direct link to Naked Order Lifecycle") Naked orders follow a simpler path: 1. You place an order through the Silhouette UI in [naked mode](https://docs.silhouette.exchange/trading/naked-trading.md) 2. The order routes directly to Hyperliquid via Builder Codes 3. The order executes on Hyperliquid's order book, fully visible 4. Your wallet and trade details are recorded on the public ledger Naked orders do not interact with the TEE or delegated wallets. They are standard Hyperliquid trades routed through Silhouette's interface. ## Order States[​](#order-states "Direct link to Order States") | State | Description | | -------------------- | ------------------------------------------------------------------------------ | | **Submitted** | Your order has been received by Silhouette | | **Processing** | The order is being processed in the TEE | | **Executing** | The order is being submitted to Hyperliquid | | **Filled** | The order has been fully executed | | **Partially Filled** | Part of the order was filled within the IoC price cap; the remainder cancelled | | **Cancelled** | The order could not fill within the IoC price cap and was cancelled in full | To learn more about [shielded trading](https://docs.silhouette.exchange/trading/shielded-trading.md) or [naked trading](https://docs.silhouette.exchange/trading/naked-trading.md), visit the relevant pages. --- # Shielded Spot Trading ## What is shielded spot trading?[​](#what-is-shielded-spot-trading "Direct link to What is shielded spot trading?") Shielded spot trading routes orders through Silhouette's Trusted Execution Environment (TEE) and settles them on Hyperliquid through delegated wallets. Delegated-wallet fills are publicly visible, but the mapping from a given fill to an individual user's wallet is not exposed on the public ledger. ## What Stays Private[​](#what-stays-private "Direct link to What Stays Private") | What the public sees | What stays private | | --------------------------------------- | ------------------------------ | | Your deposit to Silhouette | Your individual orders | | Your withdrawal from Silhouette | Your fill prices and sizes | | Aggregate volume from delegated wallets | Your balance inside Silhouette | | | Your strategy and intent | ## Supported Markets[​](#supported-markets "Direct link to Supported Markets") Shielded spot trading is live across Hyperliquid's spot order book. Shielded perpetuals are on the roadmap. | Token | Description | Markets | | ------------------------------------------------ | ------------------- | -------------------- | | ![USDC token icon](/img/tokens/usdc.png) USDC | USD Coin | Base pair | | ![HYPE token icon](/img/tokens/hype.png) HYPE | Hyperliquid | HYPE/USDC, HYPE/USDH | | ![USDH token icon](/img/tokens/usdh.jpg) USDH | Hyperliquid Dollar | USDH/USDC | | ![BTC token icon](/img/tokens/btc.png) BTC | Bitcoin | UBTC/USDC, UBTC/USDH | | ![ETH token icon](/img/tokens/eth.png) ETH | Ethereum | UETH/USDC, UETH/USDH | | ![SOL token icon](/img/tokens/sol.png) SOL | Solana | USOL/USDC | | ![ZEC token icon](/img/tokens/zec.png) ZEC | Zcash | UZEC/USDC | | ![USDT token icon](/img/tokens/usdt.svg) USDT | Tether | USDT0/USDC | | ![FART token icon](/img/tokens/fart.svg) FART | Fartcoin | UFART/USDC | | ![PUMP token icon](/img/tokens/pump.svg) PUMP | Pump Fun | UPUMP/USDC | | ![USDe token icon](/img/tokens/usde.svg) USDe | Ethena USDe | USDE/USDC | | ![PURR token icon](/img/tokens/purr.svg) PURR | Purr | PURR/USDC | | ![XAUT token icon](/img/tokens/xaut.svg) XAUT | Tether Gold | XAUT0/USDC | | ![KNTQ token icon](/img/tokens/kntq.svg) KNTQ | Kinetiq | KNTQ/USDH | | ![KHYPE token icon](/img/tokens/khype.svg) KHYPE | Kinetiq Staked HYPE | KHYPE/USDH | Additional pairs are added as Hyperliquid's spot market offering expands. ![Shielded markets asset selector showing available spot pairs](/img/app-screenshots/ShieldedMarketsSelector.png) Select the asset selector in the top-left of the trading terminal to browse available shielded spot markets ## Order Types[​](#order-types "Direct link to Order Types") ### Market Orders[​](#market-orders "Direct link to Market Orders") Market orders are live in shielded mode. Hyperliquid has no native market-order primitive - every order on Hyperliquid is a limit order with a time-in-force. A "market" order is a limit order with a slippage-derived price cap and an IoC (Immediate or Cancel) time-in-force. The webapp computes that price cap from your slippage settings, then submits the order to the TEE as a delegated IoC. If enough liquidity is available within the cap, it fills immediately; otherwise the unfilled portion cancels. ![Shielded spot market buy order](/img/app-screenshots/shielded_SpotMarketOrder_BUY.png) Shielded spot market buy ![Shielded spot market sell order](/img/app-screenshots/shielded_SpotMarketOrder_SELL.png) Shielded spot market sell ### Limit Orders[​](#limit-orders "Direct link to Limit Orders") A limit order executes at your specified price or better. You set the asset, size, and the price you are willing to pay or receive, and the order rests until it fills at that price or better, or until you cancel it. Because execution runs through delegated wallets, your price and intent stay private while the order waits on the book. ![Shielded spot limit buy order](/img/app-screenshots/shielded_SpotLimitOrder_BUY.png) Shielded spot limit buy ![Shielded spot limit sell order](/img/app-screenshots/shielded_SpotLimitOrder_SELL.png) Shielded spot limit sell ### Advanced Orders - Coming Soon[​](#advanced-orders---coming-soon "Direct link to Advanced Orders - Coming Soon") TWAP, Scale, and VWAP order types are planned for shielded mode. These will route through the same Hyperliquid order book and liquidity used by shielded market orders today. ## Use Cases[​](#use-cases "Direct link to Use Cases") Orders placed from a known wallet on a public ledger are attributable to that wallet at the point of placement. Shielded execution addresses a specific set of costs that follow from that attribution: * **Large accumulation.** Buying activity for staking, HIP-3 deployment, or longer-term positioning is not attributable to the user's wallet. This reduces the opportunity for front-running during extended accumulation. * **Strategy confidentiality.** Order flow that would otherwise reveal research, thesis, or timing is not exposed to onchain observers. Individual fills aggregate into delegated-wallet volume. * **Resistance to order-flow analysis.** Copy-trading bots, wallet trackers, and signal-aware liquidity providers have no onchain mapping from delegated-wallet fills back to individual users. * **Size execution.** Large orders that would signal market impact when placed from a known wallet are executed within aggregated delegated-wallet volume. Compare shielded trading with [naked trading](https://docs.silhouette.exchange/trading/naked-trading.md) for a breakdown of when each mode is appropriate. For the full order flow, see [Order Lifecycle](https://docs.silhouette.exchange/trading/order-lifecycle.md). For fee details, see [Fees](https://docs.silhouette.exchange/trading/fees.md). ---