Developers

Integration Guide

A developer-facing tour of the protocol. Whether you're a project team listing your token, an aggregator routing through Topaz, or a builder reading pool state for an oracle, this is the entry point.

Choose a deployment before integrating

The BNB examples below use that chain's token addresses, wrapped native asset and contracts. A spoke needs its own verified deployment bundle, RPC, factory registry, Voter and reward token. Pool creation, whitelisting, gauges and incentives are local operations; an approval or listing on BNB does not authorize the same action elsewhere.

The interface races Topaz routing, 0x and Relay on every chain pair each one serves. A Topaz winner executes through the Universal Router with Permit2; the Router and Slipstream SwapRouter examples below are direct contract integrations, not a description of every app swap.

xTOPAZ adds vault entry, LayerZero transfers, redemption and local spoke voting. These flows are enabled on the live networks. Read the multichain integration guide for chain and endpoint IDs, contract groups, receipt checks and indexing.

Common integration paths

  • ✓Aggregator / router integration — quote Topaz pools and execute swaps through Router (v2) or SwapRouter (Slipstream).
  • ✓Token listing as a project — get whitelisted, create your pool, request a gauge, post incentives.
  • ✓Oracle consumer — read TWAPs from Slipstream pools for your dapp.
  • ✓Vault / strategy builder — automate concentrated-liquidity range management or veTOPAZ voting strategies.

Routing & quoting

For programmatic swaps, three quoter contracts cover all routes:

  • ✓Router — v2-style multihop swaps. Use getAmountsOut for quoting.
  • ✓QuoterV2 — Slipstream-only multihop quotes. Off-chain only (it reverts to return data — the standard Uniswap V3 quoter pattern).
  • ✓MixedRouteQuoterV1 — quotes that mix v2 and Slipstream pools in a single path. Use this when routing across both pool types.

Encoding a Slipstream path:

solidity
// Single hop
bytes memory path = abi.encodePacked(
    tokenIn,           // 20 bytes
    uint24(tickSpacing), // 3 bytes
    tokenOut           // 20 bytes
);

// Multi-hop via WBNB
bytes memory path = abi.encodePacked(
    tokenIn,           // 20 bytes
    uint24(50),        // tickSpacing for first hop (low-vol)
    WBNB,              // 20 bytes
    uint24(200),       // tickSpacing for second hop (volatile)
    tokenOut           // 20 bytes
);

See Contracts for all addresses including the mixed-route quoter and Swaps & Routing for end-user routing concepts.

Listing a token / pool (for projects)

The complete checklist for bringing a new token onto Topaz:

  1. 1Deploy or identify the ERC-20 on the selected live Topaz network; the current examples use BNB. Standard ERC-20 only — fee-on-transfer tokens are partially supported by the v2 router but not by the Slipstream periphery.
  2. 2Create the pool. For v2: PoolFactory.createPool(tokenA, tokenB, stable). For Slipstream: CLFactory.createPool(tokenA, tokenB, tickSpacing, sqrtPriceX96). Both are permissionless.
  3. 3Seed initial liquidity. Provide both tokens at a price you're willing to defend. First deposit sets the price; subsequent depositors must match the ratio.
  4. 4Request whitelisting. Two whitelists matter: (a) token whitelist for use as bribe rewards, and (b) for new tokens, token whitelist on the Voter to allow permissionless gauge creation. Coordinate with governance — reach out via Telegram or governance forum.
  5. 5Get a gauge created. Once your token is whitelisted (or for a fully-whitelisted pair, by anyone), call Voter.createGauge(poolFactory, pool). Without a gauge, the pool exists but receives no emissions.
  6. 6Post incentives. Approve and call BribeVotingReward.notifyRewardAmount(token, amount) on the gauge's bribe contract to attract votes. See Incentives (Bribes).
⚠Custom (non-whitelisted) pairs
A gauge for a pair containing a non-whitelisted token can only be created by governance, not permissionlessly. Plan ahead if your token isn't yet on the Voter whitelist.

Reading pool state on-chain

Common reads:

  • ✓PoolFactory.getPool(tokenA, tokenB, stable) — fetch v2 pool address (returns 0x0 if absent).
  • ✓CLFactory.getPool(tokenA, tokenB, tickSpacing) — fetch Slipstream pool address.
  • ✓Voter.gauges(pool) — fetch a pool's gauge address (0x0 if none).
  • ✓Voter.isAlive(gauge) — check whether a gauge is currently active.
  • ✓CLPool.slot0() — current sqrtPriceX96, tick, observation index, etc.
  • ✓CLPool.observe([secondsAgo1, secondsAgo2]) — compute a TWAP from the in-pool oracle. See Oracles & TWAP.

Working with the gauge directly

For programmatic LP integrations:

solidity
// v2 LP token staking
ILpToken(lpToken).approve(gauge, amount);
IGauge(gauge).deposit(amount);

// Claim emissions
IGauge(gauge).getReward(msg.sender);

// Withdraw
IGauge(gauge).withdraw(amount);

// Slipstream NFT staking
INonfungiblePositionManager(npm).approve(gauge, tokenId);
ICLGauge(gauge).deposit(tokenId);
ICLGauge(gauge).getReward(tokenId);
ICLGauge(gauge).withdraw(tokenId);

Gauges follow the standard notifyRewardAmount /rewardPerToken /earned pattern from MasterChef / Synthetix. Rewards stream linearly across 604,800 seconds after each epoch's emission allocation.

Voting on behalf of a contract

Smart-contract vaults that hold veTOPAZ NFTs can vote and claim like any wallet. Standard flow:

solidity
// One-time setup: vault must own (or be approved for) the veNFT
IVoter(voter).vote(
    tokenId,
    [pool1, pool2, ...],
    [weight1, weight2, ...]
);

// Each epoch, after the flip:
IVoter(voter).claimBribes(
    [bribeContract1, ...],
    [[token1A, token1B], ...],
    tokenId
);
IVoter(voter).claimFees(
    [feeContract1, ...],
    [[token1A, token1B], ...],
    tokenId
);
ℹOne vote per epoch
The Voter enforces a single vote per NFT per epoch (with exceptions for whitelisted NFTs that can vote during the final hour). Plan vault automations accordingly — re-voting before the next epoch boundary reverts.

Indexing & subgraph

Topaz emits standard events at every state change — pool creates, swaps, mints, burns, votes, gauge distributions, and reward claims. Indexers need each deployment’s RPC logs and start blocks, or a chain-specific subgraph. If you build public indexing infrastructure for the protocol, get in touch via Telegram for cross-linking.

Continue reading