Skip to main content
The TypeScript SDK is WIP. This page shows the planned shape alongside the real HTTP + contract calls that work today. Every SDK call maps to a real endpoint documented in the Relayer API reference.
A complete Tachyon submission is two artifacts:
  1. An on-chain intent, public, created by calling BridgeIntentV2.createIntent on the source chain (solver-facing offer: token pair, amount, reward, destination)
  2. An encrypted recipient bundle, off-chain, POSTed to the relayer (who actually receives, encrypted so only the relayer and the winning solver ever see plaintext)
Both are needed. The SDK will wrap them into one call; today you make them yourself.
Tachyon is live on testnet. All transactions use test tokens with no real value.

Prerequisites

  • A sender wallet with the source-chain asset + some native gas
  • A registered recipient (see step 1)
  • The bridge contract approved for amountIn + reward

1. Register the recipient (once per recipient address)

Generates and stores the recipient’s viewing/spending keys on the relayer.
const sig = await recipientWallet.signMessage(`REGISTER_STEALTH:${recipientAddress}`);
await fetch("https://relayer.tachyon.pe/recipient/register", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ recipientAddress, signature: sig }),
});
Planned SDK:
await tachyon.user.register(recipientAddress, sig);

2. Approve the bridge contract

Sender approves tokenIn for amountIn + reward:
import { Contract } from "ethers";
const token = new Contract(tokenIn, erc20ABI, senderWallet);
await (await token.approve(bridgeAddress, amountIn + reward)).wait();

3. Call createIntent on source chain

Publishes the public offer. Returns an intentId.
const bridge = new Contract(bridgeAddress, bridgeIntentABI, senderWallet);
await (await bridge.createIntent(
  tokenIn, tokenOut,
  amountIn, minAmountOut,
  reward,
  destChainId,
  auctionDuration,  // e.g. 120 for 2 minutes
)).wait();

const intentId = (await bridge.getLatestIntentId()).toString();

4. Encrypt and store the recipient bundle

const { publicKey } = await fetch("https://relayer.tachyon.pe/ecies-pubkey").then(r => r.json());

const plaintext = JSON.stringify({
  recipients: [recipientAddress],
  amounts:    [minAmountOut.toString()],
});
const encrypted = await eciesEncrypt(publicKey, Buffer.from(plaintext));

await fetch("https://relayer.tachyon.pe/store-recipients", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    intentId,
    chainId: destChainId,
    encryptedData: encrypted.toString("hex"),
  }),
});
Planned SDK wraps steps 3+4 into:
const { intentId } = await tachyon.intent.submit({
  sourceChain: "base_mainnet",
  destChain:   "horizen_mainnet",
  tokenIn,  tokenOut,
  amountIn, minAmountOut, reward,
  deadline: Math.floor(Date.now() / 1000) + 600,
  recipients: [{ address: recipientAddress, amount: minAmountOut }],
}, senderWallet);

5. Poll to completion

async function waitForCompletion(intentId) {
  while (true) {
    const { intent } = await fetch(`https://relayer.tachyon.pe/intent-details/${intentId}`).then(r => r.json());
    console.log(intent.status); // pending → solving → settled → completed
    if (intent.status === "completed") {
      console.log("Source settle tx:", intent.settleTxHash);
      console.log("Destination solve tx:", intent.solveTxHash);
      return intent;
    }
    await new Promise(r => setTimeout(r, 3000));
  }
}
Planned SDK:
tachyon.intent.subscribe(intentId, (intent) => {
  if (intent.status === "completed") console.log(intent.settleTxHash);
});

What just happened under the hood

The only actor that ever sees the plaintext recipient address, outside of the relayer inside its trusted environment, is the one solver that won the bid for your intent.

Next steps

Concepts: mental model

Intents, solvers, stealth addresses, viewing keys, settlement.

Privacy guarantees

What’s private, what’s public, threat model.

Relayer HTTP API

Every endpoint used above, with full request/response shapes.

Errors

Error codes you’ll encounter and how to handle them.