Tempo Transactions
Tempo Transactions are a Tempo-native EIP-2718 transaction type designed for payments. They support configurable fee tokens, fee sponsorship, batched calls, concurrent nonces, access keys, and scheduled execution. They are recommended over Ethereum transactions on Tempo.
Setup
In order to use Tempo Transactions, ensure that you have set up your Viem client
with the tempoModerato chain.
import { , } from 'viem'
import { } from 'viem/accounts'
import { } from 'viem/chains'
export const = ({
: ('0x...'),
: ,
: (),
})Now that you have set up your Viem client, you can now start to leverage Tempo Transactions. Check out the features below on what is enabled with Tempo Transactions.
Features
Pay Fees with Stablecoins
Use the feeToken field to pay fees in any USD-denominated TIP-20 token. Tempo's Fee AMM automatically swaps to the validator's preferred token.
import { } from './viem.config'
const = '0x20c0000000000000000000000000000000000001'
const = await .({
: '0xdeadbeef',
: ,
: '0xcafebabecafebabecafebabecafebabecafebabe',
})Fee Sponsorship
A fee payer can cover gas fees for the sender via the feePayer field. You can use a local account or a remote relay service.
import { } from './viem.config'
import { } from 'viem/accounts'
const = ('0x...')
const = await .({
: '0xdeadbeef',
,
: '0xcafebabecafebabecafebabecafebabecafebabe',
})Batch Calls
Bundle multiple operations atomically with calls.
import { } from './viem.config'
const = await .({
: [
{
: '0xcafebabecafebabecafebabecafebabecafebabe',
: '0xdeadbeef0000000000000000000000000000000001',
},
{
: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef',
: '0xcafebabe0000000000000000000000000000000001',
},
],
})Access Keys
Access keys enable you to delegate signing authority from a primary account to a secondary key, such as device-bound non-extractable WebCrypto key. The primary account signs a key authorization that grants the access key permission to sign transactions on its behalf.
This authorization is then attached to the next transaction (that can be signed by either the primary or the access key), then all transactions thereafter can be signed by the access key.
import { , } from 'viem/tempo'
import { } from './viem.config'
// 1. Instantiate account.
const = .('0x...')
// 2. Generate a non-extractable WebCrypto key pair & instantiate access key.
const = await .()
const = .(, {
: ,
})
// 3. Sign over key authorization with account.
const = await .()
// 4. Attach key authorization to (next) transaction.
const = await .({
: , // sign transaction with access key
: '0xdeadbeef0000000000000000000000000000000001',
,
: '0xcafebabecafebabecafebabecafebabecafebabe',
})Concurrent Transactions
Concurrent transactions enable higher throughput by allowing multiple transactions from the same account to be sent in parallel without waiting for sequential nonce confirmation.
By using different nonce keys, you can submit multiple transactions simultaneously that don't conflict with each other, enabling parallel execution and significantly improved transaction throughput for high-activity accounts.
You can leverage concurrent transactions in Viem by using Promise.all.
import { } from './viem.config'
const [, , ] = await .([
.({
: '0xdeadbeef0000000000000000000000000000000001',
: '0xcafebabecafebabecafebabecafebabecafebabe',
}),
.({
: '0xcafebabe0000000000000000000000000000000001',
: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef',
}),
.({
: '0xdeadbeef0000000000000000000000000000000001',
: '0xcafebabecafebabecafebabecafebabecafebabe',
}),
])You can also have control over the nonceKeys
import { } from './viem.config'
const = await .({
: '0xdeadbeef0000000000000000000000000000000001',
: 567n,
: '0xcafebabecafebabecafebabecafebabecafebabe',
})
const = await .({
: '0xdeadbeef0000000000000000000000000000000001',
: 789n,
: '0xcafebabecafebabecafebabecafebabecafebabe',
})Scheduled Transactions
Scheduled transactions allow you to sign a transaction in advance and specify a time window for when it can be
executed onchain. By setting validAfter and validBefore timestamps, you define the earliest and latest times
the transaction can be included in a block.
import { } from './viem.config'
const = await .({
: '0xdeadbeef0000000000000000000000000000000001',
: '0xcafebabecafebabecafebabecafebabecafebabe',
: .((new ('2026-01-01')) / 1000),
: .((new ('2026-01-02')) / 1000),
})More Resources
- Tempo protocol docs: Tempo Transactions
- Tempo Viem setup: Getting Started
- Tempo transports:
withFeePayer