Sealed-bid RFQs, HTLC atomic settlement, and a Model Context Protocol server that lets Claude trade for you.
Trading crypto OTC has always been a trust problem. You find a counterparty on Telegram, negotiate a price, and hope nobody front-runs or ghosts. Institutions do it over Bloomberg chat. Retail does it on DEXs and eats slippage.
We built Hashlock Markets to fix both sides — and then we gave AI agents the keys.
What is Hashlock Markets?
Hashlock Markets (hashlock.markets) is an intent-based trading protocol for swapping any asset — crypto, RWAs, and stablecoins — with private sealed bids and verified counterparties.
Here's how it works:
- You declare an intent — "I want to sell 10 ETH for USDC, minimum price $3,200."
- Market makers respond with sealed bids — nobody sees anyone else's price.
- Best bid wins — transparent settlement via Hash Time-Locked Contracts (HTLCs).
- Atomic settlement — both sides of the trade execute simultaneously, or neither does. No escrow. No trust.
The result: zero slippage, no front-running, and no information leakage before execution.
A note on the name: "Hashlock" refers to our trading platform and brand — Hashlock Markets, built by Hashlock-Tech. We are not affiliated with Hashlock Pty Ltd (hashlock.com), the Australian smart contract auditing firm. Our protocol uses the cryptographic hash-lock primitive (as in HTLCs), but "Hashlock" as a product name refers to this trading platform specifically.
Why AI Agents?
Here's the thing about intent-based trading: it's perfectly suited for AI agents.
An intent is just structured data — asset pair, amount, direction, constraints. There's no chart to read, no order book to stare at. You express what you want, and the protocol finds the best execution.
This is exactly how LLMs think. They're great at understanding natural language ("swap 5 ETH for USDC, best price, settle on Ethereum") and terrible at pixel-level chart analysis. Intent trading plays to their strengths.
So we built an MCP server.
The Hashlock MCP Server
The Hashlock MCP server implements the Model Context Protocol — the open standard that lets AI assistants like Claude, GPT, and others interact with external tools.
Five Core Tools
The server exposes five tools that cover the full trading lifecycle:
create_intent — Create a new trading intent with asset pair, amount, direction, and price constraints. Supports ETH, BTC, SUI, USDC, USDT, and any ERC-20.
validate_intent — Check an intent for correctness before submission. Catches issues like insufficient balance, invalid pairs, or malformed parameters.
commit_intent — Lock an intent on-chain, triggering the sealed-bid RFQ process. Market makers see the intent but not each other's bids.
explain_intent — Get a human-readable breakdown of what an intent will do, including estimated fees, settlement chain, and time-lock parameters.
parse_natural_language — Convert plain English into a structured intent. "Sell 2 BTC for USDC on Ethereum, minimum $68k" becomes a valid intent object.
Two Ways to Connect
stdio (local) — Install via npm and run locally:
npx -y @hashlock-tech/mcp
Streamable HTTP (remote) — Connect directly to our hosted endpoint:
https://hashlock.markets/mcp
Both require a SIWE (Sign-In with Ethereum) bearer token for authentication. You sign once with your wallet at hashlock.markets/sign/login, and the token is valid for 30 days.
Cross-Chain by Default
Hashlock Markets supports settlement on Ethereum, Bitcoin, and Sui — with more chains coming. The HTLC mechanism is chain-agnostic: as long as both chains support hash verification and time locks, atomic settlement works.
This means an AI agent can execute a trade like "swap 1 BTC on Bitcoin mainnet for 20 ETH on Ethereum" — and both legs settle atomically. No bridge. No wrapped tokens. No custodian.
For Market Makers
If you're running a trading desk or market-making operation, Hashlock Markets gives you:
- Sealed bids — Your pricing stays private until settlement.
- No adverse selection — You see the intent, not a limit order that's already been front-run.
- Programmable responses — Use the MCP server to build automated RFQ response bots.
- Multi-chain settlement — Settle on whatever chain has the best liquidity for you.
Getting Started
As a Trader (via Claude or any MCP client)
Add this to your Claude Desktop config (claude_desktop_config.json):
{
"mcpServers": {
"hashlock": {
"command": "npx",
"args": ["-y", "@hashlock-tech/mcp"],
"env": {
"HASHLOCK_ACCESS_TOKEN": "your-siwe-token"
}
}
}
}
Then just ask Claude: "Create an intent to sell 5 ETH for USDC at minimum $3,200 per ETH."
As a Developer
npm install @hashlock-tech/mcp
The server is MIT-licensed. Fork it, extend it, build your own trading strategies on top.
- npm: @hashlock-tech/mcp
- GitHub: Hashlock-Tech/hashlock-mcp-server
- MCP Registry: io.github.Hashlock-Tech/hashlock
What's Next
We're working on:
- Multi-leg intents — Chain complex trades (e.g., sell BTC → buy ETH → stake on Lido) into a single atomic execution.
- Limit orders with expiry — Set a price and walk away. The MCP server watches and executes.
- Portfolio rebalancing — Tell your AI agent your target allocation, and it figures out the trades.
- More chains — Solana and Arbitrum are next.
The Bigger Picture
We believe the future of trading is declarative. You say what you want, not how to get it. AI agents handle execution. Protocols handle settlement. Humans handle strategy.
Hashlock Markets is the infrastructure layer for that future.
Hashlock Markets is built by Hashlock-Tech. Try it at hashlock.markets.
Questions? Reach out on GitHub or join the conversation.
Top comments (4)
This is a really interesting direction — especially the intent → solver → execution model.
Curious how you handle this case:
intent is executed
confirmation is lost (timeout / network)
system retries the same intent
At that point, how do you distinguish:
“execute again”
vs
“resolve what already happened”
In trading / payouts this turns into duplicate execution under uncertainty.
Great question — this is exactly the at-least-once vs exactly-once boundary, and HTLCs give us a surprisingly clean answer.
The trick is that every intent becomes content-addressed before it ever hits a chain. When the trade is committed,
we generate a preimage s and derive H = hash(s). From that moment on, H is the deduplication key for the entire trade — not the intent ID, not a request nonce, but the cryptographic commitment itself.
So the retry path is never "execute again, hope for the best." It's:
Because the HTLC contract reverts on a duplicate H (you can't create two HTLCs with the same hashlock), the chain itself enforces uniqueness — even if our retry logic is buggy, double-execution is physically impossible at the settlement layer. Worst case is a wasted gas estimation.
The DB-side state machine (PENDING → INITIATOR_LOCKED → BOTH_LOCKED → CLAIMED → COMPLETED) is the second layer.
Every transition is guarded by ON CONFLICT DO NOTHING plus a "current state must be X" check, and the resolver paths that race chain-watcher events are explicitly idempotent — e.g. COMPLETED → COMPLETED is a no-op, not an error. (We learned that one the hard way on Sui, where the indexer sometimes beats the resolver back.)
Then the preimage itself does the rest. Claiming requires revealing s on-chain, so once a claim lands, every observer in the world can derive the same global truth. There's no "did it happen?" — there's the chain, and you read it.
And the timelock is the deterministic backstop. If the system retries forever, the network stays partitioned, both sides crash — eventually the timelock expires and funds refund atomically. No human escalation, no support ticket,
no double-payout window.
That's a really clean design — using H as the global dedup key and letting the chain enforce uniqueness essentially removes the "did it happen?" question at settlement entirely.
The gap I keep running into is one step earlier — before anything reaches the chain. If create_intent or the RFQ fanout is triggered but the agent loses confirmation and retries, you can get duplicate intents or repeated solver load even though settlement stays safe.
Same idea as H, just applied before the protocol boundary. Treat the invocation itself as content-addressed, claim it before kicking off the flow, retries resolve against that claim instead of re-triggering.
Curious if that's intentionally left to the caller or if there's handling at the intent layer I missed.
that pre-H invocation layer is the right place to flag the approach is to dedupe one step lower than a client wrapper would: at the gateway boundary itself, content-addressed by (toolName, canonical input, caller subject), so the property holds whether the MCP host bothers to set an idempotency header or not :) Settlement-layer atomicity (the H content-addressing) covers everything downstream; the gateway-level claim covers everything upstrem of H, which covers the problem you described.