Hedera testnet · run preflight before the transfer

Preflight.

Your users acquire and hold any Hedera token without ever hitting TOKEN_NOT_ASSOCIATED_TO_ACCOUNT. Tokens are acquired on SaucerSwap, a live DEX on Hedera testnet, and the kit picks the right one of four association mechanisms and tells you why it chose it.

Everything on this page is live and read without a wallet, a key, or a .env file.

The same transfer, before and after

8.737s apart

Three real transactions on Hedera testnet, 8.737 seconds apart, in consensus order. The only thing that changed between the first and the last is that the kit associated the token. Every row links to HashScan — check them rather than believing them.

  1. Before+0.000s
    TOKEN_NOT_ASSOCIATED_TO_ACCOUNT

    Zero token transfers are attached. Nothing moved, and the sender still paid the fee.

    no token transfers attachedverify on HashScan ↗
  2. The kit acts+4.078s
    SUCCESS

    The native adapter explicitly associated the token. The recipient authorized and paid for its association.

    no token transfers attachedverify on HashScan ↗
  3. After+8.737s
    SUCCESS

    The identical transfer, to the identical account. The only required state change was the association.

    0.0.10505627 −100 → 0.0.10733127 +100verify on HashScan ↗

Token 0.0.10733126 (PFE, 2 decimals — deliberately not 8) sent from 0.0.10505627 to 0.0.10733127, an account created with zero automatic association slots. Ordered by consensus timestamp, not by transaction id — under concurrency those two disagree.

What this relay will actually let you do

relay/0.80.2

Read live from the relay's undocumented /config endpoint. None of these values appear in the Hedera documentation, and several contradict what an Ethereum developer would assume.

LimitValueWhat it means for you
Chain id296Hedera testnet. Safe to write to.
eth_getLogs block range1000 blocksQueries wider than this return empty rather than erroring, which looks exactly like 'there were no events'. Page your log queries.
Rate limit200 requestsPer IP, per window. Shared with everyone else on this public relay.
Call data size128 KiBTransactions with larger calldata are rejected before execution.
PaymasterdisabledNo gasless transactions. The relay ships a paymaster and has it switched off, so every user needs their own HBAR for fees.

SaucerSwap, right now

The DEX this template acquires tokens on. Remove it and there is no token to acquire and no journey — the integration is load-bearing, not decorative.

Swaps, all time
1,044,228
on testnet
Total value locked
$772,415
Tokens listed
741
any of which your users may hold

Why this kit never assumes decimals

Every token on this DEX, grouped by how many decimal places it uses. Code that assumes 8 — or 18 — is wrong about a large share of them, and wrong silently: the amount still looks plausible.

0 dp39
1 dp3
2 dp78
3 dp17
4 dp9
5 dp4
6 dp165
7 dp2
8 dp395
9 dp10
11 dp1
13 dp1
18 dp17

13 distinct decimal scales across 741 tokens. This is why units.ts uses branded types: an 8-decimal value cannot be passed where 18 is expected without a compile error.

How this is put together

The whole design on one screen. Everything of value sits in a framework-free core that never imports React, so it runs from a route handler, a script, a test, or another framework entirely.

Read from
Mirror node
accounts, tokens, association state
JSON-RPC relay
live balances, limits from /config
SaucerSwap REST
token list, decimals, prices
SaucerSwap router
real quotes, the swap itself
All public. No wallet, no key.
lib/onboarding — framework-free
selectStrategy()
Pure. No network, no SDK, no signer. Given a situation it returns one of four association mechanisms and a sentence explaining the choice. Seven invariants hold across all 192 possible inputs.
1association
2address duality
3key types
4key rotation
5decimals
6read consistency
7status codes
8relay limits
Nothing here imports React.
Routes
/
Server Component · no wallet
/diagnose
Server Component · no wallet
/acquire
quote is free · only signing needs a wallet
The journey, and its order
quoteassociateswap

That order is enforced, not suggested. SaucerSwap's own documentation warns that a swap to an account without the output token associated fails with TOKEN_NOT_ASSOCIATED_TO_ACCOUNT, so the swap stays disabled until the account can actually hold the token.

See every trap on one screen

Paste any Hedera account — try 0.0.2 — and the diagnose page shows its address form, whether ECRECOVER can be trusted on it, its key type, how many automatic association slots it has left, and what will break. No wallet, no key.