Skip to main content
The TypeScript SDK is WIP. The methods below are the planned surface. Each method maps to one or more endpoints in the Relayer HTTP API, those endpoints are live today and you can integrate against them directly.

SDK ↔ API mapping

Two services back the SDK:
SDK callService endpointStatus
tachyon.health()Relayer GET /health✅ Live
tachyon.user.register(addr, sig)Relayer POST /recipient/register✅ Live
tachyon.user.listStealthAddresses(addr, sig)Relayer GET /recipient/addresses✅ Live
tachyon.user.deriveStealthKey(addr, stealthAddr, sig)Relayer POST /recipient/derive-stealth-key✅ Live
tachyon.user.deploySafe(stealthAddr, sig, chainId)Relayer POST /recipient/deploy-safe✅ Live
tachyon.recipient.relay(safeAddr, txParams, sig)Relayer POST /recipient/relay-proxy✅ Live
tachyon.intent.storeRecipients(intentId, encrypted)Relayer POST /store-recipients✅ Live
tachyon.intent.status(intentId)Relayer GET /intent-details/:intentId✅ Live
tachyon.intent.verify(intentId, network, sourceChainId)Relayer POST /verify✅ Live
tachyon.intent.settle(...)Relayer POST /settle✅ Live (solver/relayer use)
tachyon.routes.list(filter)Relayer POST /get-routes✅ Live
tachyon.twap.getECIESPubKey()TWAP GET /ecies-pubkey✅ Live
tachyon.twap.getAddress()TWAP GET /address✅ Live
tachyon.twap.create(encrypted, sig, msg)TWAP POST /orders✅ Live (raw API)
tachyon.twap.status(orderId)TWAP GET /orders/:orderId✅ Live
tachyon.twap.list(user)TWAP GET /orders?user=✅ Live
tachyon.twap.cancel(orderId, sig, msg)TWAP POST /orders/:orderId/cancel✅ Live
tachyon.intent.submit(params, wallet)BridgeIntentV2.createIntent + Relayer POST /store-recipients (combined)🟡 SDK convenience over the two-step flow
tachyon.intent.createOnChain(params, wallet)BridgeIntentV2.createIntent (on-chain only)🟡 Wrapper around contract call
tachyon.intent.subscribe(intentId, handler)Polls Relayer GET /intent-details/:intentId🟡 Polling shim until webhooks ship
tachyon.intent.submitBatch(signedBatch)Loops intent.submit (today)🔴 Planned as atomic batch
tachyon.twap.buildAndSubmit(params)SDK wraps encrypt + sign + POST /orders🔴 Planned SDK helper
tachyon.user.exportRecord(opts)(viewing-key export)🔴 Planned
tachyon.webhooks.register(opts)(webhook delivery)🔴 Planned
Legend: ✅ live now · 🟡 SDK convenience over existing surface · 🔴 planned, not yet implemented

Initialization

new Tachyon(opts: TachyonOptions): Tachyon

interface TachyonOptions {
  network: "testnet" | "mainnet";
  endpoint?: string; // override default: https://relayer.tachyon.pe
}

tachyon.health(): Promise<HealthResponse>
HealthResponse shape matches GET /health (API ref).

User & viewing key

tachyon.user.register(
  recipientAddress: Address,
  signature: Hex,            // sig over `REGISTER_STEALTH:<address>`
): Promise<RegisterRecipientResponse>

tachyon.user.listStealthAddresses(
  recipientAddress: Address,
  signature: Hex,
): Promise<StealthAddress[]>

tachyon.user.deriveStealthKey(
  recipientAddress: Address,
  stealthAddress: Address,
  signature: Hex,            // sig over `DERIVE_STEALTH_KEY:<recipient>:<stealth>`
): Promise<DeriveStealthKeyResponse>

tachyon.user.deploySafe(
  stealthAddress: Address,
  signature: Hex,            // spend-key sig over `DEPLOY_SAFE:<stealth>:<chainId>`
  chainId: string,
): Promise<DeploySafeResponse>
WIP. Selective-disclosure exports (exportRecord, exportRecords) are planned. Today, derive the stealth key via deriveStealthKey and produce a record client-side using the keys.

Intent, single

tachyon.intent.submit(
  params: IntentParams,
  wallet: Signer,
): Promise<{ intentId: string; createIntentTxHash: TxHash }>

tachyon.intent.status(intentId: string): Promise<IntentDetails>

tachyon.intent.subscribe(
  intentId: string,
  handler: (status: IntentDetails) => void,
  opts?: { intervalMs?: number },
): Unsubscribe
submit does both halves of the real two-step flow:
  1. Signs and sends BridgeIntentV2.createIntent with the public fields (tokenIn, tokenOut, amountIn, minAmountOut, reward, destChainId, auctionDuration)
  2. Fetches the relayer’s ECIES public key, encrypts { recipients, amounts }, and posts to POST /store-recipients
status polls GET /intent-details/:intentId. subscribe is a polling helper (default 3 s) until webhooks ship. The lower-level variants are exposed for integrations that only need one half:
tachyon.intent.createOnChain(
  params: OnChainIntentParams,
  wallet: Signer,
): Promise<{ intentId: string; txHash: TxHash }>

tachyon.intent.storeRecipients(
  intentId: string,
  destChainId: number,
  recipients: { address: Address; amount: bigint }[],
): Promise<void>

Intent, batch (planned)

tachyon.intent.submitBatch(signed: SignedBatch): Promise<{ intentIds: string[] }>
Planned. Today, payroll loops submit over each contributor.

TWAP

Base URL: https://twap.tachyon.pe. See the full TWAP API reference for request/response shapes.
tachyon.twap.getECIESPubKey(): Promise<{ publicKey: Hex }>
tachyon.twap.getAddress():     Promise<{ address: Address }>

tachyon.twap.create(args: {
  encrypted: Hex;      // ECIES-encrypted TWAPOrderParams
  signature: Hex;      // personal_sign over `message`
  message: string;     // must recover to order.user
}): Promise<{ orderId: string; order: TWAPOrder }>

tachyon.twap.status(orderId: string): Promise<TWAPOrder>
tachyon.twap.list(user: Address):     Promise<TWAPOrder[]>

tachyon.twap.cancel(
  orderId: string,
  args: { signature: Hex; message: string },
): Promise<void>

// Planned helper, wraps encrypt + sign + create in one call
tachyon.twap.buildAndSubmit(
  params: TWAPOrderParams,
  wallet: Signer,
): Promise<{ orderId: string; order: TWAPOrder }>
The raw-API variants (create, cancel) are available today over HTTP. The buildAndSubmit helper is a planned SDK convenience.

Recipient

tachyon.recipient.relay(
  safeAddress: Address,
  exec: { to: Address; value: string; data: Hex; operation: 0 | 1 },
  signature: Hex,            // stealth-key sig over Safe tx hash
  chainId: string,
): Promise<{ txHash: Hex }>

tachyon.recipient.listIncoming(
  recipientAddress: Address,
  signature: Hex,
): Promise<IncomingIntent[]>
relay wraps POST /recipient/relay-proxy for gasless sweeps/spends from a stealth Safe. listIncoming is a convenience over GET /recipient/addresses plus per-address chain queries.

Routes & solvers

tachyon.routes.list(filter?: GetRoutesRequest): Promise<GetRoutesResponse>
Wraps POST /get-routes. Returns supported chain pairs and registered solvers.

Webhooks (planned)

tachyon.webhooks.register(opts: {
  url: string;
  events: WebhookEvent[];
  secret: string;
}): Promise<{ webhookId: string }>

verifyTachyonSignature(
  rawBody: Buffer,
  signature: string,
  secret: string,
): boolean
Planned. Until webhooks ship, poll GET /intent-details/:intentId (typically every 2–5 seconds while an intent is live).

Types

type ChainId = "horizen_mainnet" | "base_mainnet" | string;
type Address = `0x${string}`;
type Hex     = `0x${string}`;
type TxHash  = `0x${string}`;

interface IntentDetails {
  intentId: string;
  sourceChainId: string;
  destChainId: string;
  solverAddress: string;
  depositTxHash?: TxHash;
  solveTxHash?: TxHash;
  settleTxHash?: TxHash;
  status: "pending" | "solving" | "settled" | "completed";
  timestamp: string;
  settledAt?: string;
}

interface StealthAddress {
  address: Address;
  ephemeralPubKey: Hex;
  chainId: string;
  intentId: string;
  safeDeployed: boolean;
  safeAddress?: Address;
  createdAt: number;
}

interface IncomingIntent {
  intentId: string;
  destChain: ChainId;
  destAsset: Address;
  amount: bigint;
  stealthAddress: Address;
  swept: boolean;
  settledAt: number;
}

interface TWAPOrderParams {
  user: Address;
  assetIn: Address;
  assetOut: Address;
  chainIn: string;          // e.g. "base_mainnet"
  chainOut: string;
  sourceChainId: number;
  destChainId: number;
  totalAmountIn: string;
  amountPerPeriod: string;
  period: number;           // seconds, min 5
  startTime: number;        // unix seconds
  endTime: number;          // unix seconds, > startTime
  recipients: Address[];
  amounts: string[];
  permitSignature?: Hex;
}

interface TWAPOrder extends TWAPOrderParams {
  id: string;
  status: "active" | "completed" | "cancelled";
  tranchesFilled: number;
  totalTranches: number;
  amountSpent: string;
  intentIds: string[];      // BridgeIntent IDs, one per fired tranche
  createdAt: string;
  lastExecutedAt?: string;
}

Relayer HTTP API

Intent lifecycle, stealth addresses, sweeps.

TWAP HTTP API

TWAP order creation, status, cancellation.