Sealed RFQ, HTLC atomic settlement, and a Model Context Protocol server that lets Claude trade for you.
Update, October 2026. This post was first published in April 2026. It has been revised to match the product as it is live today: six mainnet chains (Bitcoin, Ethereum, TRON, Solana, Base, Robinhood Chain), API key authentication, and the current MCP tool set. Current reference: https://docs.hashlock.markets
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 a non-custodial atomic P2P cross-chain swap protocol: Bitcoin to EVM, TRON and Solana, via sealed RFQ and HTLC. Two parties swap assets across chains directly, with no bridge and no custodian.
Here's how it works:
- A taker posts an RFQ: "I want to sell 10 ETH on Ethereum for USDT on TRON."
- Makers answer privately: sealed quotes, no public price book, nobody sees anyone else's price.
- Both sides agree terms: the counterparties negotiate in a thread and accept.
- Atomic settlement via HTLC: both legs settle, or both refund after their timelocks. No custodian. No trust.
The result: no 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?
An RFQ 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 counterparties compete to fill it.
This is exactly how LLMs work best. They're great at understanding natural language ("swap 5 ETH for USDC, best price, settle on Base") and terrible at pixel-level chart analysis. RFQ 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.
The Tool Set
The hosted server exposes 24 tools covering the full trading lifecycle:
-
Discovery:
whoami,list_assets,list_open_rfqs,get_rfq -
Taker side:
create_rfq,cancel_rfq,list_my_rfqs,request_listing -
Maker side:
quote_rfq,list_rfq_threads,get_thread -
Negotiation:
propose_price,accept_proposal,accept_terms -
Settlement:
set_swap_address,build_fund,build_claim,build_refund,broadcast_tx,swap_status,list_swaps -
Wallet proofs:
wallet_proof_message,prove_wallet,remove_wallet_proof
The hosted server is strictly non-custodial: it returns unsigned transactions, and the initiator generates and keeps the HTLC secret locally.
Two Ways to Connect
Hosted (Streamable HTTP): add one URL to your MCP client. The client discovers it needs authorization, sends you to Hashlock to approve with a wallet signature, and receives its own API key over OAuth 2.1:
https://hashlock.markets/mcp
Clients that do not speak OAuth send a key you created yourself: Authorization: Bearer hk_live_.... Keys are valid for 90 days.
Local (stdio): run the npm package with your own chain keys in the environment. This server can sign and settle without a human in the loop:
npx -y @hashlock-tech/mcp
An autonomous agent needs neither a browser nor an email: it mints its own API key with a wallet signature alone (GET /v1/keys/nonce, then POST /v1/keys).
Cross-Chain by Default
Hashlock Markets settles on Bitcoin, Ethereum, TRON, Solana, Base and Robinhood Chain. The HTLC mechanism is chain-agnostic: as long as both chains support SHA-256 hash verification and time locks, atomic settlement works.
This means an AI agent can execute a trade like "swap 1 BTC on Bitcoin for 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 quotes: your pricing stays private.
- No adverse selection: you see the RFQ, not a limit order that's already been front-run.
- A maker feed: a WebSocket stream of new RFQs you can quote over the same socket.
- Multi-chain settlement: settle on whichever chain has the best liquidity for you.
Getting Started
As a Trader (via Claude or any MCP client)
Add the hosted URL to your MCP client and approve with your wallet when prompted. For a local server with your own keys, add this to claude_desktop_config.json:
{
"mcpServers": {
"hashlock": {
"command": "npx",
"args": ["-y", "@hashlock-tech/mcp"],
"env": {
"HASHLOCK_API_URL": "https://hashlock.markets/api",
"HASHLOCK_EVM_KEY": "0x<agent EVM key>"
}
}
}
}
Then just ask Claude: "Create an RFQ to sell 5 ETH for USDT on TRON."
As a Developer
npm install @hashlock-tech/mcp
The server is MIT-licensed. Fork it, extend it, build your own trading strategies on top.
- Docs: docs.hashlock.markets
- npm: @hashlock-tech/mcp
- GitHub: Hashlock-Tech/hashlock-mcp
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.