How one blind request becomes one fill
The grid floor from above, an orange cable routed between two hatches
Plan of the floor

Run a maker

Any wallet can quote on DarkHooks. A maker is an HTTPS endpoint that answers requests with signed two-sided quotes, and a wallet that holds and approves the inventory behind them.

1. setEndpoint(url)once, on the contract2. bond $DARKHOOKSquotes settle once bondedPOST url {pair, size}from the relay, no side3. sign Quotebid, ask, size, 30 s4. approve DarkDeskboth legs, held in your wallet
An external maker: register, bond, answer requests, keep both legs approved.

1. Get the SDK

The SDK is one file that depends only on viem. It is served by this site.

mkdir darkhooks-maker && cd darkhooks-maker && npm init -y && npm i viem
curl -sO https://darkhooks.app/sdk/darkhooks.mjs
curl -sO https://darkhooks.app/sdk/maker-example.mjs

2. Answer requests

The relay POSTs this body to your endpoint and waits 1.5 seconds. There is no side in it.

{ "type": "rfq", "requestId": "…", "chainId": 4663, "desk": "0x0785646d7323F274E20E287A883E60679097082A",
  "pair": "NVDA", "base": "0xd060…", "quote": "0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168",
  "size": "400000000000000", "respondWithinMs": 1500 }

Reply with a signed quote, or with 204 to stand aside:

{ "quote": { "maker": "0xYou…", "base": "0xd060…", "quote": "0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168",
             "bid": "212100000", "ask": "212400000", "size": "400000000000000",
             "expiry": 1792698630, "nonce": "77012…" },
  "signature": "0x…", "name": "My maker" }
import { privateKeyToAccount } from "viem/accounts";
import { makerHandler } from "./darkhooks.mjs";

const handle = makerHandler(privateKeyToAccount(process.env.MAKER_KEY), async ({ pair, size }) => {
  const mid = await myMid(pair);            // your own price
  return { bid: mid * 0.9996, ask: mid * 1.0004, size: Number(size) / 1e18 };
});

3. Register and bond

cast send 0x0785646d7323F274E20E287A883E60679097082A "setEndpoint(string)" "https://your-host/rfq" \
  --rpc-url https://rpc.mainnet.chain.robinhood.com --private-key $MAKER_KEY
# after approving $DARKHOOKS to the contract:
cast send 0x0785646d7323F274E20E287A883E60679097082A "bond(uint256)" <amount> --rpc-url … --private-key $MAKER_KEY

The relay reads EndpointSet events and only calls makers for which canQuote(maker) is true, which requires the minimum bond once $DARKHOOKS is bound to the contract. Until then, only house agents settle.

4. Keep both legs approved

cast send <base token> "approve(address,uint256)" 0x0785646d7323F274E20E287A883E60679097082A $(cast max-uint) …
cast send 0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168 "approve(address,uint256)" 0x0785646d7323F274E20E287A883E60679097082A $(cast max-uint) …

Quote only what you hold. A fill against a quote you cannot honour costs you part of your bond, paid to the taker. To pull quotes you have already sent, call cancelNonces.