Tempo RPC: A Developer's Guide (Chain ID 4217)

By John Sullivan · October 17, 2026 · 8 min read · #tempo #tempo rpc #stablecoins #payments #developer guide

Tempo is a chain built for payments. It runs the EVM, accepts ordinary Ethereum transactions, and answers the usual eth_ methods, but it has no native token. Gas is paid in dollar stablecoins, blocks arrive about twice a second and are final when they arrive, and there is a new transaction type, 0x76, that batches calls and lets someone else pay the fee.

Most of that is good news for a payments backend. It also breaks a few assumptions that EVM code makes without thinking: that eth_getBalance means something, that timestamp is unique per block, and that every transaction has one to address. Everything below was measured against the live chain on October 17, 2026, through the SwiftNodes endpoint and Tempo's public RPC.

The endpoint

https://rpc.swiftnodes.io/rpc/tempo?key=YOUR_API_KEY
wss://rpc.swiftnodes.io/ws/tempo?key=YOUR_API_KEY
import { createPublicClient, http, defineChain } from "viem";

const tempo = defineChain({
  id: 4217,
  name: "Tempo",
  // Tempo has no native token. viem requires this field, so it is a placeholder:
  // never read balances or fees from it.
  nativeCurrency: { name: "USD", symbol: "USD", decimals: 18 },
  rpcUrls: { default: { http: ["https://rpc.swiftnodes.io/rpc/tempo?key=YOUR_API_KEY"] } },
});

const client = createPublicClient({ chain: tempo, transport: http() });

What we measured

Property Value
Chain ID 4217 (0x1079)
Client tempo/v1.16.1-acfc30e/x86_64-unknown-linux-gnu
Block 1 January 16, 2026
Block interval 551 ms on average (517 to 596 ms over 100 blocks)
Finality immediate: safe = finalized = latest
Block gas limit 500,000,000
Activity 92 transactions in 400 blocks; 318 blocks empty
Base fee 600,000,000, flat across eth_feeHistory
eth_maxPriorityFeePerGas 0
Fee currency USD stablecoins (6 decimals)
eth_getBalance the same huge constant for every address
eth_getLogs 20,000 results per request
Tracing callTracer works; the default tracer does not
WebSocket newHeads works: 18 heads in 10 seconds

There is no native token

This is the first thing that will surprise your code. We called eth_getBalance on a busy sender, on address 0x…0001, and on the same sender a thousand, a million, twenty million and forty-four million blocks back. Every call returned the same value:

0x9612084f0316e0ebd5182f398e5195a51b5ca47667d4c9b26c9b26c9b26c9b2

That is about 4.2 × 10^75, a sentinel, not a balance. eth_getProof for the same account reports "balance": "0x0". So a wallet screen, a "has enough gas?" check or a portfolio tracker that reads eth_getBalance shows nonsense, and a check that compares it with a fee always passes.

Money on Tempo lives in TIP-20 tokens, which answer the ERC-20 interface. The ones we saw had addresses starting with 0x20c0:

Token Address Decimals Supply
pathUSD 0x20c0000000000000000000000000000000000000 6 51.2 million
USDC.e 0x20c000000000000000000000b9537d11c60e8b50 6 25.1 million
OUSD 0x20c0000000000000000000006a37da5c996874be 6 529 million

Read balances the ERC-20 way:

import { erc20Abi, formatUnits } from "viem";

const raw = await client.readContract({
  address: "0x20c000000000000000000000b9537d11c60e8b50", // USDC.e
  abi: erc20Abi,
  functionName: "balanceOf",
  args: [account],
});
console.log(formatUnits(raw, 6)); // dollars

symbol, decimals, totalSupply and Transfer events all behave like ERC-20, so indexers built for tokens carry over unchanged.

Fees are paid in dollars

Every block we sampled had a base fee of exactly 600,000,000 and a priority fee of zero. Those numbers are not gwei of anything. The receipt names the token that paid (feeToken) and who paid (feePayer), and the fee itself shows up as a Transfer of that token to 0xfeec000000000000000000000000000000000000. Comparing that transfer with gasUsed × effectiveGasPrice gives the conversion:

Transaction Gas used gasUsed × price Fee transfer In dollars
Type 0x2 contract call 26,579 1.59 × 10^13 16 units USDC.e $0.000016
Type 0x76 batched payment 54,670 3.28 × 10^13 33 units USDC.e $0.000033

So the price works out as 10^-18 dollars per unit, and a 6-decimal stablecoin is charged gasUsed × gasPrice ÷ 10^12 units, rounded up. A plain USDC.e transfer estimated at 38,284 gas, which is about $0.000023.

Two consequences:

  • Plain Ethereum transactions work but still pay in stablecoins. The 0x2 transaction above has no feeToken field of its own, yet its receipt shows USDC.e paid the fee. The sender needs a stablecoin balance, not "ETH".
  • Fee code should read the receipt, not assume a native token. To show what a user paid, take feeToken from the receipt and decode the Transfer to the 0xfeec… address, or compute gasUsed × effectiveGasPrice ÷ 10^12.

The 0x76 transaction type

Of the 92 transactions in our 400-block sample, 73 were type 0x76, Tempo's own format, and only 9 were standard EIP-1559 (0x2). A 0x76 transaction carries fields no other EVM chain has:

Field What it holds
calls an array of {to, value, input}: several calls in one transaction
feeToken the stablecoin to pay with (it was null in our sample, and the receipt still named USDC.e)
feePayerSignature a second signature from whoever sponsors the fee
nonceKey, nonce a nonce plus a key, so one account can run parallel nonce lanes
validBefore, validAfter a time window, after which the transaction can no longer be included
signature an object with a signature type (secp256k1 here), a version and a keyId
keyAuthorization, aaAuthorizationList delegated keys and account authorizations

The receipt adds feeToken and feePayer, and its to is the first call's target. Three practical points:

  • A transaction decoder that only knows types 0 to 4 will reject or mis-parse 0x76. If you store raw transactions, keep unknown types as JSON rather than dropping them.
  • One transaction can move money to several places. Index the Transfer logs, not the transaction's to and value.
  • Parallel nonce lanes change the nonce management story: a payout service can send on several nonceKey lanes without one stuck transaction blocking the rest.

Half-second blocks and millisecond timestamps

Over 100 consecutive blocks the interval was 551 ms on average, never under 517 ms or over 596 ms. That breaks the assumption that timestamp is unique: the standard field is in seconds, so two consecutive blocks often share a timestamp, and we saw intervals of 0 and 1 seconds. Tempo adds timestampMillis (and timestampMillisPart) to every block. Use it for ordering and latency metrics.

Blocks also carry a consensusContext with epoch, view, parentView and proposer, which is the consensus round that produced the block.

For live data, a WebSocket subscription is the comfortable choice at this speed. Through our endpoint, eth_subscribe("newHeads") delivered 18 headers in 10 seconds. Polling over HTTP every second works too, but you will get two blocks per poll. Reconnect handling matters more at 2 blocks per second; see reconnecting a WebSocket without losing events.

Instant finality

eth_getBlockByNumber("safe")      -> 44526575
eth_getBlockByNumber("finalized") -> 44526575
eth_getBlockByNumber("latest")    -> 44526575

All three tags return the same block. Tempo is one of the chains with zero finality lag in our survey of the finalized block tag across 62 chains. For a payments product this is the headline feature: once the receipt exists, the payment is final, so you can mark an invoice paid without a confirmation count. Code that waits for finalized works as written and simply never waits.

Logs: 20,000 results per request

eth_getLogs is capped by result count, not block range:

Range Result
1,000 blocks 1,016 logs
10,000 blocks 10,784 logs
100,000 blocks query exceeds max results 20000, retry with the range 44426969-44441423

The error names a range that would fit, here about 14,000 blocks. That is a convenient retry signal, but it is computed for unfiltered traffic at that moment. Filter by address and topics and you can usually cover far more blocks per call. At 550 ms per block, 14,000 blocks is only about two hours of chain, so plan backfills in many requests. More on the different kinds of caps in eth_getLogs range caps.

Receipts and tracing

eth_getBlockReceipts works and includes the feeToken and feePayer fields. eth_estimateGas works as usual.

Tracing needs care. With {"tracer": "callTracer"}, debug_traceTransaction returns a proper call tree, and for a 0x76 transaction the top-level call goes to the zero address with one child per entry in calls. The default struct-log tracer did not: for the Tempo transactions and the block we tried, it returned "failed": true with empty structLogs, even for transactions whose receipt status is 1. trace_transaction returned a placeholder action with zero addresses. So use callTracer, and never take failed from the default tracer as the outcome; take status from the receipt.

Method Result
eth_getLogs works, 20,000-result cap
eth_getBlockReceipts works, with feeToken and feePayer
eth_getBalance returns a constant; use balanceOf
safe / finalized equal to latest
debug_traceTransaction with callTracer works
Default tracer, trace_transaction placeholder output for 0x76
eth_subscribe("newHeads") works over WebSocket

Summary

  • Payments chain, chain ID 4217, no native token. Fees are paid in 6-decimal USD stablecoins.
  • eth_getBalance returns the same huge constant for every address. Read balanceOf on pathUSD, USDC.e or other TIP-20 tokens.
  • A fee is gasUsed × gasPrice ÷ 10^12 stablecoin units: a contract call costs a few thousandths of a cent.
  • Most traffic is type 0x76: batched calls, sponsored fees, parallel nonces. Index Transfer logs, not to and value.
  • 550 ms blocks: use timestampMillis. Finality is immediate.
  • eth_getLogs is capped at 20,000 results; trace with callTracer.

Tempo endpoints and method support are on our Tempo RPC page, with 127 other chains on the same key. For another stablecoin-first chain, compare Plasma. SwiftNodes has a free tier to try it.

J
John Sullivan
Infrastructure Writer, SwiftNodes

John Sullivan covers RPC infrastructure, node operations, and multi-chain development at SwiftNodes — what it actually takes to keep endpoints fast, fresh, and reliable across EVM and non-EVM networks.

Related posts

  • Morph RPC: A Developer's Guide (Chain ID 2818)

    Morph is a payments-focused Ethereum L2 with its own transaction type for paying gas in tokens. Measured: ~2 s blocks, a 0.001 gwei base fee, a transfer costing ~$0.002 (97% L1 data), MorphTx (0x7f) paying gas in USDC, extra receipt fields, safe equal to finalized at ~18 minutes, and full tracing.

  • Etherlink RPC: A Developer's Guide (Chain ID 42793)

    Etherlink is the EVM rollup on Tezos. Measured: sub-second to 1.5 s blocks, a fixed 1 gwei base fee, plain transfers that use 621,000 gas because the data fee is charged as gas, a 500-block eth_getLogs cap, and no safe tag.

  • Bitlayer RPC: A Developer's Guide (Chain ID 200901)

    Bitlayer is an EVM chain that pays gas in BTC. Measured: 3-second blocks from 21 rotating validators, a hard 0.025 gwei minimum tip, a transfer that costs 52.5 satoshis, no safe or finalized tags, and a public RPC that keeps only recent state.

Try SwiftNodes free — multi-chain RPC across 83 networks, flat-rate pricing, pay by card or crypto, no KYC. Get an API key in 30 seconds →