SDK Client#
Installation#
Bash
1npm install @tetrafi/sdk1 linesbash
Python requires 3.10+, httpx, websockets.
Initialization#
TypeScript
1import { TetraFi } from "@tetrafi/sdk";23const tetrafi = new TetraFi({4 apiKey: process.env.TETRAFI_API_KEY!,5 environment: "sandbox", // "sandbox" | "production"6 timeout: 30000, // ms, default 300007 retries: 3, // auto-retry on 5xx8});8 linestypescript
apiKey / api_keystringrequired- Your API key (tfk_test_* for sandbox, tfk_live_* for production)
environmentstring- 'sandbox' | 'production'. Defaults to 'production'.Default:
production timeoutnumber- Request timeout (ms in TS, seconds in Python).Default:
30000 / 30 retriesnumber- Auto-retry count on 5xx errors.Default:
3 baseUrl / base_urlstring- Override the API base URL. Useful for proxies or local development.
Core Methods#
rfq.create(params) Stable#
Submit a new RFQ to competing solvers.
TypeScript
1const rfq = await tetrafi.rfq.create({2 pair: "USDC/USDT",3 side: "buy",4 amount: "1000000.00",5 corridor: "ethereum-optimism",6 maxSlippage: 0.001,7});7 linestypescript
Annotated parameters
1const rfq = await tetrafi.rfq.create({2pair: "USDC/USDT",3side: "buy",4amount: "1000000.00",5corridor: "ethereum-optimism",6maxSlippage: 0.001,7});7 linestypescript
ReturnsRFQ
rfq.getQuotes(rfqId) / rfq.get_quotes(rfq_id) Stable#
Get competing quotes for an active RFQ. Returns list sorted best-price-first.
TypeScript
1const quotes = await tetrafi.rfq.getQuotes("rfq_abc123");1 linestypescript
rfq.acceptBest(rfqId) / rfq.accept_best(rfq_id)#
Automatically select and accept the best available quote.
TypeScript
1const settlement = await tetrafi.rfq.acceptBest("rfq_abc123");1 linestypescript
ReturnsSettlement
quotes.accept(quoteId) / quotes.accept(quote_id)#
Accept a specific quote and trigger escrow creation.
TypeScript
1const settlement = await tetrafi.quotes.accept("qt_xyz789");1 linestypescript
ReturnsSettlement
settlements.get(id)#
Get the current status of a settlement.
TypeScript
1const settlement = await tetrafi.settlements.get("stl_abc123");1 linestypescript
ReturnsSettlement
compliance.check(address)#
Check whether an address has a valid compliance attestation.
TypeScript
1const status = await tetrafi.compliance.check("...");1 linestypescript
ReturnsComplianceStatus
events.on(type, callback) Beta#
Subscribe to real-time events via WebSocket. TypeScript uses a callback pattern; Python uses async for.
TypeScript
1const unsubscribe = tetrafi.events.on("settlement.complete", (event) => {2 console.log("Settled:", event.settlement.id);3});45// Later: stop receiving events6unsubscribe();6 linestypescript
| Channel | When it fires |
|---|---|
rfq.created | Your RFQ has been broadcast to solvers |
quote.received | A solver returned a quote |
quote.accepted | You accepted a quote |
settlement.pending | Settlement initiated, escrow locking |
settlement.complete | Both legs settled atomically |
settlement.failed | Settlement reverted, refund issued |
rfq.* / settlement.* | Wildcard - all events in that namespace |
Full Working Example#
TypeScript
1import { TetraFi } from "@tetrafi/sdk";23const tetrafi = new TetraFi({4 apiKey: process.env.TETRAFI_API_KEY!,5 environment: "sandbox",6});78async function executeSwap() {9 // 1. Create RFQ10 const rfq = await tetrafi.rfq.create({11 pair: "USDC/USDT",12 side: "buy",13 amount: "1000000.00",14 });1516 // 2. Wait for auction window17 await new Promise((r) => setTimeout(r, 3000));18 const quotes = await tetrafi.rfq.getQuotes(rfq.id);19 if (quotes.length === 0) throw new Error("No quotes");2021 // 3. Accept best price22 const settlement = await tetrafi.rfq.acceptBest(rfq.id);2324 // 4. Monitor to completion25 let status = settlement;26 while (!["complete", "failed", "refunded"].includes(status.status)) {27 await new Promise((r) => setTimeout(r, 5000));28 status = await tetrafi.settlements.get(settlement.id);29 }3031 console.log(status.status === "complete" ? "Success!" : `Failed: ${status.status}`);32}3334executeSwap().catch(console.error);34 linestypescript
Error Handling#
TypeScript
1import { TetraFiError, RateLimitError, AuthError, ComplianceError } from "@tetrafi/sdk";23try {4 const rfq = await tetrafi.rfq.create({ pair: "USDC/USDT", side: "buy", amount: "1000000" });5} catch (e) {6 if (e instanceof RateLimitError) {7 await sleep(e.retryAfter * 1000);8 } else if (e instanceof AuthError) {9 console.error("Invalid API key");10 } else if (e instanceof ComplianceError) {11 console.error("Compliance check failed");12 } else if (e instanceof TetraFiError) {13 console.error("API error:", e.code, e.message);14 } else {15 throw e;16 }17}17 linestypescript
Type Definitions#
TypeScript
1interface RFQ {2 id: string;3 pair: string;4 side: "buy" | "sell";5 amount: string;6 corridor: string;7 status: "pending" | "quoting" | "accepted" | "expired";8 createdAt: string;9 expiresAt: string;10}1112interface Quote {13 id: string;14 rfqId: string;15 solverId: string;16 price: string;17 ttl: number;18 confidence: number;19 createdAt: string;20}2122interface Settlement {23 id: string;24 rfqId: string;25 quoteId: string;26 status: "pending" | "escrow_locked" | "filling" | "complete" | "failed" | "refunded";27 originTxHash?: string;28 destinationTxHash?: string;29 amount: string;30 createdAt: string;31 settledAt?: string;32}3334interface ComplianceStatus {35 address: string;36 isCompliant: boolean;37 attestationHash: string;38 expiresAt: string;39}39 linestypescript
Versioning#
Both packages follow semver. Pin to exact versions for production deploys.
| Bump | Meaning | Action |
|---|---|---|
1.0.x → 1.0.y | Patch - bug fixes | Auto-update safe |
1.0.x → 1.1.x | Minor - new methods | Read changelog |
1.x → 2.0 | Major - breaking | Migration guide required |