Fastest-chain built for
enterprise-scale payments

Sub-second transactions, sub-cent fees.

21,200 TPS settled at peak load
508 ms average block time
$1.8M to sponsor 10M users
1.25 Ggas/s peak execution rate
21,200 TPS settled at peak load
BLOCK TIME508ms
COST$1.8M
PEAK CAPACITY1.25 Ggas/s

SETTLED TPS

21,200TPS

Tempo settled ~92% of submitted benchmark load while sustaining high-volume throughput.

Performance Dashboard

Build on Tempo

Tempo's infrastructure is well-suited for high-throughput transactions, public and private stablecoin payments

Built for programmable payments

Tempo brings payments, accounts, stablecoins, and compliance primitives into the protocol layer.

Tempo Transactions

Tempo Transactions let apps batch, sponsor, schedule, and parallelize payments through a native transaction type.

Batch callsBundle multiple payments into a single transaction
import { client } from "./viem.config";
 
// Calls execute atomically in one tx
const receipt = await client.sendTransactionSync({
calls: [
{ to: usdc, data: transferData(alice, 10n) },
{ to: usdc, data: transferData(bob, 25n) },
],
});
Fee SponsorshipSponsor fees so users do not need to hold gas
import { parseUnits } from "viem";
import { client } from "./viem.config";
 
// App pays gas via a fee-payer signature
const { receipt } = await client.token.transferSync({
token: usdc,
to: alice,
amount: parseUnits("10", 6),
feePayer: sponsor,
});
Concurrent TransactionsRun parallel payment flows without nonce bottlenecks
import { client } from "./viem.config";
 
// Expiring nonces drop the nonce ordering
const opts = { token: usdc, nonceKey: "expiring" };
 
const [a, b] = await Promise.all([
client.token.transferSync({ ...opts, to: alice, amount }),
client.token.transferSync({ ...opts, to: bob, amount }),
]);
Scheduled TransactionsSign now, execute within a defined time window
import { client } from "./viem.config";
 
const now = Math.floor(Date.now() / 1000);
 
// Valid only inside this time window
const receipt = await client.sendTransactionSync({
to: usdc,
data: transferData(alice, 10n),
validAfter: now,
validBefore: now + 3600,
});
Read transaction docs

Accounts

Tempo gives wallets and apps more flexible account access with passkeys, delegated keys, and scoped signing authority.

Passkey signingLet users sign with WebAuthn and P256 keys.
import { createConfig, http } from "wagmi";
import { tempo } from "wagmi/chains";
import { webAuthn } from "accounts/wagmi";
 
// Sign with a passkey — WebAuthn / P256
export const config = createConfig({
chains: [tempo],
connectors: [webAuthn({ authUrl: "/auth" })],
transports: { [tempo.id]: http() },
});
Access keysDelegate signing authority to secondary keys.
import { generatePrivateKey } from "viem/accounts";
import { Account, Actions, Expiry } from "viem/tempo";
import { client } from "./viem.config";
 
// Delegate signing to a scoped access key
const accessKey = Account.fromP256(generatePrivateKey(), {
access: client.account,
});
 
const auth = await Actions.accessKey.signAuthorization(
client,
{ accessKey, expiry: Expiry.days(7) },
);
Scoped permissionsLimit what a key can sign or access.
import { Actions, Expiry } from "viem/tempo";
import { parseUnits } from "viem";
import { client } from "./viem.config";
 
// Cap spend and scope which calls a key makes
const auth = await Actions.accessKey.signAuthorization(client, {
accessKey,
expiry: Expiry.days(7),
limits: [{ token: usdc, limit: parseUnits("100", 6) }],
scopes: [{
target: usdc,
selector: "transfer(address,uint256)",
}],
});
Multi-device accessBuild wallet flows that feel closer to consumer apps.
import { createConfig, http } from "wagmi";
import { tempo } from "wagmi/chains";
import { tempoWallet } from "accounts/wagmi";
 
// One passkey account, portable across devices
export const config = createConfig({
chains: [tempo],
connectors: [tempoWallet()],
transports: { [tempo.id]: http() },
});
Read account docs

TIP-20 Tokens

TIP-20 gives stablecoins the primitives needed for payments: fees, memos, lanes, policies, rewards, and issuer controls.

Stablecoin feesPay network fees directly in supported stablecoins.
import { parseUnits } from "viem";
import { client } from "./viem.config";
 
// Send alphaUSD, pay the fee in betaUSD
const { receipt } = await client.token.transferSync({
token: alphaUsd,
to: alice,
amount: parseUnits("100", 6),
feeToken: betaUsd,
});
Transfer memosAttach payment references, invoice IDs, or notes.
import { parseUnits, stringToHex, pad } from "viem";
import { client } from "./viem.config";
 
// Attach a 32-byte invoice reference
const memo = pad(stringToHex("INV-12345"), { size: 32 });
 
const { receipt } = await client.token.transferSync({
token: usdc,
to: alice,
amount: parseUnits("100", 6),
memo,
});
Payment lanesReserve blockspace for predictable payment execution.
import { parseUnits } from "viem";
import { client } from "./viem.config";
 
// TIP-20 transfers use the reserved payment
// lane automatically — predictable inclusion
const { receipt } = await client.token.transferSync({
token: usdc,
to: alice,
amount: parseUnits("100", 6),
});
Issuer controlsMint, burn, pause, cap supply, and manage roles.
import { parseUnits } from "viem";
import { client } from "./viem.config";
 
// Issuer-only supply & emergency controls
await client.token.mintSync({
token: usdc,
to: treasury,
amount: parseUnits("1000000", 6),
});
await client.token.setSupplyCapSync({ token: usdc, supplyCap });
await client.token.pauseSync({ token: usdc });
Read TIP-20 docs

TIP-403 Policies

TIP-403 lets issuers define transfer rules once and reuse them across tokens, wallets, and payment flows.

Policy registryCreate reusable policies instead of custom token logic.
import { client } from "./viem.config";
 
// Create one policy, reuse it everywhere
const { policyId } = await client.policy.createSync({
admin,
type: "whitelist",
addresses: [alice, bob],
});
AllowlistsRestrict transfers to approved participants.
import { client } from "./viem.config";
 
// Only approved addresses can transfer
await client.policy.modifyWhitelistSync({
policyId,
address: alice,
allowed: true,
});
BlocklistsPrevent restricted addresses from sending or receiving.
import { client } from "./viem.config";
 
// Block specific addresses; all others allowed
await client.policy.modifyBlacklistSync({
policyId,
address: mallory,
restricted: true,
});
Shared enforcementApply the same policy across multiple tokens.
import { client } from "./viem.config";
 
// Apply one policy across many tokens
for (const token of [alphaUsd, betaUsd, gbpUsd]) {
await client.token.changeTransferPolicySync({
token,
policyId,
});
}
Read policy docs

Zones

Zones let developers create controlled payment spaces for private economies, closed-loop stablecoins, and restricted payment flows.

Private environmentsCreate isolated payment spaces for specific use cases.
import { createPublicClient, http } from "viem";
import { zoneModerato } from "viem/tempo/zones";
 
// Private validium chain, anchored to Tempo
const zone = createPublicClient({
chain: zoneModerato(6),
transport: http("https://rpc-zone-a.testnet.tempo.xyz"),
});
Controlled accessDefine who can participate in a payment environment.
import { parseUnits } from "viem";
import { Actions } from "viem/tempo";
 
// Encrypted: only the sequencer sees the details
const { receipt } = await Actions.zone.encryptedDepositSync(
rootClient,
{
account: rootClient.account,
token: pathUsd,
amount: parseUnits("100", 6),
zoneId: ZONE_A.id,
},
);
Asset boundariesKeep stablecoins and payment flows inside a defined zone.
import { parseUnits } from "viem";
import { Actions } from "viem/tempo";
 
// Move pathUSD in; it stays private inside
const { receipt } = await Actions.zone.depositSync(rootClient, {
account: rootClient.account,
token: pathUsd,
amount: parseUnits("100", 6),
zoneId: ZONE_A.id,
});
Composable rulesCombine zones with token policies and account controls.
import { parseUnits } from "viem";
import { Actions } from "viem/tempo";
 
// Routed exit — zones inherit TIP-403 policies
const { receipt } = await Actions.zone.requestWithdrawalSync(
rootClient,
{
account: rootClient.account,
token: pathUsd,
amount: parseUnits("50", 6),
zoneId: ZONE_A.id,
},
);
Read zone docs