A minimal, TEE-aware Request-For-Quote (RFQ) system for takers and makers.
This project implements a minimal RFQ (Request for Quote) engine that connects takers (who request prices) and makers (who respond with quotes).
It is designed to demonstrate architectural reasoning, fairness, and testability
The system is built to simulate a Trusted Execution Environment (TEE) and is extensible to include real-world integrations such as APIs, smart contracts, and eligibility policies.
- TEE Awareness: All critical logic executes within a simulated trusted enclave (
TrustedContext.execute()), separating trusted computation from the untrusted API layer. - Fairness and Privacy: Makers can view only their own quotes; takers see all quotes for transparency.
- Testability: Logic is cleanly separated from transport and storage layers for unit testing with Jest.
- Extensibility: Optional modules (HTTP API, WebSocket, smart-contract adapter, eligibility) extend the system without changing core logic.
- Clarity: Code is minimal and organized to show architectural trade-offs rather than production completeness.
| File | Description |
|---|---|
src/infra/trustedContext.ts |
Simulates a Trusted Execution Environment (TEE) boundary. All RFQ and quote operations are executed within this sandbox. |
src/infra/memoryStore.ts |
Lightweight in-memory persistence for RFQs and quotes. Provides isolated state for each execution. |
src/service/rfqService.ts |
Core business logic handling RFQ creation, quote submission, and fairness enforcement. |
src/service/eligibilityService.ts |
Implements a simple whitelist mechanism for maker eligibility with add/remove methods. |
src/onchain/contractAdapter.ts |
Optional adapter that integrates with a local Ethereum testnet (Anvil) via ethers.js to record RFQs on-chain. |
src/api/apiServer.ts |
Express + Socket.IO API exposing /rfq, /quote, and /quotes endpoints. Handles REST calls and real-time quote updates. |
src/demo.ts |
CLI demo for running the RFQ creation and quote submission flow directly in Node.js. |
src/tests/rfqService.test.ts |
Jest test suite validating fairness, quote visibility, and core business rules. |
src/tests/stretchGoals.test.ts |
Unit tests for eligibility add/remove and whitelist logic. |
npm install typescript jest ts-jest @types/jest express socket.io body-parser ethersnpx ts-jest config:initnpx jestnpx ts-node src/demo.tsStart the API server:
npx ts-node src/api/apiServer.tsServer starts on http://localhost:4000.
curl -X POST http://localhost:4000/rfq -H "Content-Type: application/json" -d '{"takerId":"taker1","assetPair":"BTC/USDT","notional":10,"expiry":"2025-12-31T23:59:59Z"}'curl -X POST http://localhost:4000/quote -H "Content-Type: application/json" -d '{"rfqId":"1730558300011","makerId":"makerA","price":67800}'curl http://localhost:4000/quotes/1730558300011/takerimport { io } from "socket.io-client";
const socket = io("http://localhost:4000");
socket.on("rfq_created", (data) => console.log("RFQ Created:", data));
socket.on("quote_submitted", (data) => console.log("Quote Submitted:", data));Expected output:
RFQ Created: { id:'1730...', takerId:'taker1', assetPair:'BTC/USDT' }
Quote Submitted: { makerId:'makerA', rfqId:'1730...', price:67800 }
- Start a local Anvil or Hardhat chain:
anvil-
Deploy
RFQRegistry.solwith a simpleregisterRFQevent. -
Register an RFQ via the adapter:
import { ContractAdapter } from "./onchain/contractAdapter";
import RFQRegistryABI from "../contracts/RFQRegistry.json";
const adapter = new ContractAdapter(
"http://127.0.0.1:8545",
"0xYourContractAddress",
RFQRegistryABI
);
adapter.registerRFQ("0xabc123hash", "taker1");import { EligibilityService } from "./service/eligibilityService";
EligibilityService.isMakerEligible("makerA"); // true
EligibilityService.addMaker("newMaker");
EligibilityService.removeMaker("makerA");| Test Suite | Description |
|---|---|
rfqService.test.ts |
Core fairness and quote-isolation verification |
stretchGoals.test.ts |
Eligibility add/remove and whitelist behavior |
MIT License - for educational and demonstration purposes only.