terminal8mix API

REST API for integrating the 8mix privacy layer (TRON / TRC-20 USDT) into third-party products.

Base URL: https://api.8mix.gg


Non-custodial privacy mixer for TRC-20 USDT on TRON. 13 endpoints for pool queries, unsigned transaction building, and relayer-assisted withdrawals.

The API never handles user secrets — note generation, ZK proof computation, and private key management are strictly client-side.


Response Format

All responses follow the same JSON envelope:

{ "ok": true, "data": { ... } }
{ "ok": false, "error": "Error description" }

Rate Limits

Scope
Limit
Window

All /api/* endpoints

120 requests

60 seconds

POST /api/relayer/withdraw

5 requests

60 seconds

Rate limit headers included in every response: ratelimit-limit, ratelimit-remaining, ratelimit-reset.


Denominations

Valid denominations: 100, 500, 1000, 3000, 5000, 10000 (USDT).

All raw values are in SUN (6 decimals): 100 USDT = 100000000.


Pools

GET /api/pools

List all pools with balance, Merkle root, and relayer fee.

Field
Type
Description

denomination

number

Pool denomination in USDT

denominationRaw

string

Denomination in SUN (6 decimals)

address

string

Pool contract address (base58)

poolBalance

number

Current pool USDT balance

poolBalanceRaw

string

Pool balance in SUN

currentRoot

string

Current Merkle tree root (bytes32 hex)

relayerFee

number

Relayer fee in USDT


GET /api/pools/:denom

Single pool info. Returns relayerFeeRaw in addition to list fields.


GET /api/pools/:denom/root

Current Merkle tree root for a pool.


POST /api/pools/:denom/check-spent

Check if a nullifier has been spent (withdrawal already processed).

Body field
Type
Required
Format

nullifierHash

string

yes

0x + 64 hex chars (bytes32)


POST /api/pools/:denom/can-withdraw

Pre-check withdrawal validity before generating a proof. Verifies that the nullifier is not spent and the root is known.

Body field
Type
Required
Format

nullifierHash

string

yes

bytes32 hex

root

string

yes

bytes32 hex

Possible responses:


Wallet Queries

GET /api/balance/:address

USDT balance of a TRON address.

Field
Type
Description

balance

number

USDT balance (human-readable)

balanceRaw

string

Balance in SUN


GET /api/allowance/:address/:denom

USDT allowance granted by address to the pool contract.

Field
Type
Description

allowance

string

Current allowance in SUN

sufficient

boolean

true if allowance >= denomination


Transaction Builders

These endpoints return unsigned TronWeb-compatible transaction objects. The client must sign with the user's wallet and broadcast to TRON.

POST /api/tx/approve

Build an unsigned USDT approve transaction.

Body field
Type
Required
Description

owner

string

yes

TRON address (base58)

denomination

string

yes

100, 1000, or 3000

Sign with tronWeb.trx.sign(transaction) and broadcast with tronWeb.trx.sendRawTransaction(signed).


POST /api/tx/deposit

Build an unsigned deposit transaction. User must have approved USDT first.

Body field
Type
Required
Format

owner

string

yes

TRON address (base58)

denomination

string

yes

100, 1000, or 3000

commitment

string

yes

bytes32 hex — Poseidon(nullifier, secret)


POST /api/tx/withdraw

Build an unsigned withdraw transaction. User pays gas. For gasless withdrawal, use /api/relayer/withdraw instead.

Body field
Type
Required
Format

caller

string

yes

TRON address (who signs the tx)

denomination

string

yes

100, 1000, or 3000

proof

string

yes

0x + 512 hex chars (Groth16 proof)

root

string

yes

bytes32 hex

nullifierHash

string

yes

bytes32 hex

recipient

string

yes

TRON address

relayer

string

no

TRON address (defaults to 8mix relayer)


Relayer

The relayer signs and broadcasts withdrawal transactions on behalf of users, covering all gas/energy costs. A fixed fee of 4 USDT is deducted from the withdrawal amount.

GET /api/relayer/status

Check if the relayer is configured and available.

Field
Type
Description

enabled

boolean

true if relayer private key is configured

address

string|null

Relayer TRON address, or null if disabled


POST /api/relayer/withdraw

Submit a withdrawal via relayer. The relayer verifies the ZK proof off-chain, then signs and broadcasts the transaction. Recipient receives denomination - 4 USDT.

Rate limited: 5 requests per minute.

Body field
Type
Required
Format

denomination

string

yes

100, 1000, or 3000

proof

string

yes

0x + 512 hex chars (Groth16 proof)

root

string

yes

bytes32 hex

nullifierHash

string

yes

bytes32 hex

recipient

string

yes

TRON address (who receives USDT)

Success:

Errors:

HTTP
Error
Meaning

400

Invalid proof

Proof format invalid

400

Invalid ZK proof

Proof failed off-chain verification

400

Proof verification failed

snarkjs rejected the proof

400

Root expired — regenerate proof

Merkle root no longer in contract history

409

Note already spent

Nullifier was already used

429

Relay rate limit — try again in a minute

Rate limit exceeded

503

Relayer not available

Relayer private key not configured

Security: The relayer verifies the ZK proof off-chain (snarkjs.groth16.verify) before spending gas on an on-chain transaction. Duplicate requests with the same nullifier are blocked by an in-memory mutex.


Health

GET /api/health


Error Reference

All errors follow the same format:

HTTP
Error
When

400

Invalid denomination. Use: 100, 1000, 3000

Unknown denomination

400

Invalid TRON address

Malformed base58 address

400

Invalid nullifierHash (bytes32 hex)

Not 0x + 64 hex

400

Invalid commitment (bytes32 hex)

Not 0x + 64 hex

400

Invalid proof (hex string expected)

Not 0x + 512 hex

400

Invalid JSON body

Malformed request body

400

Invalid ZK proof

Proof failed off-chain verification

400

Root expired — regenerate proof

Merkle root expired from history

404

Pool not configured

Pool missing in server config

404

Not found

Unknown route

409

Note already spent

Nullifier already used

413

Request body too large

Body exceeds 10KB

429

Too many requests, try again later

Global rate limit exceeded

429

Relay rate limit — try again in a minute

Relayer rate limit exceeded

500

Internal server error

Unhandled error (production)

503

Relayer not available

Relayer not configured


Integration Guide

Deposit Flow

Note format: 8mix-{denomination}-{nullifierHex}{secretHex} where nullifier and secret are each 62 hex characters (31 bytes from crypto.getRandomValues). The commitment is Poseidon(nullifier, secret).

Withdrawal via Relayer (gasless)

Self-Withdrawal (user pays gas)


Smart Contracts

Contract
Address
Network

EightMix 100 USDT

TEd3WceUmLB25bqygmk6zgZjhAYnSryTNc

TRON Mainnet

EightMix 1,000 USDT

TCY3LAEtVKicxaP1jDC47KSVvykeB2nwhX

TRON Mainnet

EightMix 3,000 USDT

TVSY8gM1tGSBgzT3naiRmRAbCmyn6ZUdjA

TRON Mainnet

USDT (TRC-20)

TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t

TRON Mainnet

Relayer

TAWHckA571Cu3h8njup8Bv5oqXGdtwuX2T

TRON Mainnet


Self-Hosting

Installation

Required Environment Variables

Nginx Reverse Proxy

PM2 Commands


8mix — https://8mix.gg

Last updated