This guide will walk you through connecting to the Tempo testnet, getting testnet tokens, and making your first TIP-20 transfer.
Prerequisites
Choose your preferred method:
Command Line (cast)
TypeScript SDK
Install Foundry:curl -L https://foundry.paradigm.xyz | bash
foundryup
You’ll need Node.js 18+ and npm/yarn/pnpm installed.
Step 1: Connect to testnet
Tempo testnet is called Moderato. It’s a public network for testing and development.
Testnet connection details:
| Property | Value |
|---|
| Network Name | Tempo Testnet (Moderato) |
| Chain ID | 42431 |
| Currency | USD |
| RPC URL | https://rpc.moderato.tempo.xyz |
| WebSocket | wss://rpc.moderato.tempo.xyz |
| Block Explorer | https://explore.tempo.xyz |
Verify connectivity
Test that you can connect to the network:
cast block-number --rpc-url https://rpc.moderato.tempo.xyz
You should see the current block number.import { ProviderBuilder } from 'alloy';
import { TempoNetwork } from 'tempo-alloy';
const provider = await ProviderBuilder.new_with_network<TempoNetwork>()
.connect('https://rpc.moderato.tempo.xyz');
const blockNumber = await provider.getBlockNumber();
console.log(`Current block: ${blockNumber}`);
Step 2: Get testnet tokens
You’ll need testnet stablecoins to pay for gas and test transfers. The faucet provides AlphaUSD tokens.
Testnet tokens have no real value. Don’t send real funds to testnet addresses.
Using the faucet RPC method
The fastest way to get testnet tokens is via the tempo_fundAddress RPC method:
# Replace <YOUR_ADDRESS> with your Ethereum address
cast rpc tempo_fundAddress "<YOUR_ADDRESS>" \
--rpc-url https://rpc.moderato.tempo.xyz
Example:cast rpc tempo_fundAddress "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb" \
--rpc-url https://rpc.moderato.tempo.xyz
This will send you testnet AlphaUSD tokens and return the transaction hash.import { ProviderBuilder } from 'alloy';
import { TempoNetwork } from 'tempo-alloy';
const provider = await ProviderBuilder.new_with_network<TempoNetwork>()
.connect('https://rpc.moderato.tempo.xyz');
const address = '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb';
const txHashes = await provider.request({
method: 'tempo_fundAddress',
params: [address]
});
console.log('Funded! Transaction hashes:', txHashes);
Check your balance
Verify you received the tokens:
# AlphaUSD token address
export ALPHA_USD="0x20c0000000000000000000000000000000000001"
export YOUR_ADDRESS="0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb"
cast call $ALPHA_USD "balanceOf(address)(uint256)" $YOUR_ADDRESS \
--rpc-url https://rpc.moderato.tempo.xyz
The balance is returned in token units (6 decimals). Divide by 1,000,000 to get the USD amount.import { address } from 'alloy/primitives';
import { ITIP20 } from 'tempo-alloy/contracts/precompiles';
const alphaUSD = ITIP20.new(
address('0x20c0000000000000000000000000000000000001'),
provider
);
const balance = await alphaUSD.balanceOf(
address('0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb')
);
console.log(`Balance: ${balance.toString()} tokens (${balance / 1_000_000n} USD)`);
Step 3: Make your first transfer
Now let’s send a TIP-20 transfer. TIP-20 is Tempo’s enhanced token standard that extends ERC-20 with payment-specific features.
Basic transfer
# Set up your environment
export ALPHA_USD="0x20c0000000000000000000000000000000000001"
export RECIPIENT="0x70997970C51812dc3A010C7d01b50e0d17dc79C8"
export RPC_URL="https://rpc.moderato.tempo.xyz"
export PRIVATE_KEY="0x..." # Your private key
# Send 10 USD (10,000,000 units with 6 decimals)
cast send $ALPHA_USD "transfer(address,uint256)" \
$RECIPIENT 10000000 \
--rpc-url $RPC_URL \
--private-key $PRIVATE_KEY
You’ll see the transaction hash and receipt once it’s confirmed.import { ProviderBuilder } from 'alloy';
import { TempoNetwork } from 'tempo-alloy';
import { ITIP20 } from 'tempo-alloy/contracts/precompiles';
import { address, U256 } from 'alloy/primitives';
// Connect to testnet
const provider = await ProviderBuilder.new_with_network<TempoNetwork>()
.connect(process.env.RPC_URL || 'https://rpc.moderato.tempo.xyz');
// AlphaUSD token
const alphaUSD = ITIP20.new(
address('0x20c0000000000000000000000000000000000001'),
provider
);
// Send 10 USD (10,000,000 units with 6 decimals)
const receipt = await alphaUSD
.transfer(
address('0x70997970C51812dc3A010C7d01b50e0d17dc79C8'),
U256.from(10_000_000)
)
.send()
.await
.get_receipt()
.await;
console.log(`Transfer successful! Hash: ${receipt.transaction_hash}`);
Transfer with memo
One of TIP-20’s key features is the ability to include memos for payment reconciliation:
# Convert memo to bytes32 (left-padded)
# For invoice "INV-12345"
cast send $ALPHA_USD "transferWithMemo(address,uint256,bytes32)" \
$RECIPIENT \
10000000 \
"$(cast --format-bytes32-string 'INV-12345')" \
--rpc-url $RPC_URL \
--private-key $PRIVATE_KEY
import { B256 } from 'alloy/primitives';
const receipt = await alphaUSD
.transferWithMemo(
address('0x70997970C51812dc3A010C7d01b50e0d17dc79C8'),
U256.from(10_000_000),
B256.left_padding_from('INV-12345'.as_bytes())
)
.send()
.await
.get_receipt()
.await;
console.log(`Transfer with memo successful! Hash: ${receipt.transaction_hash}`);
Memos are stored on-chain as bytes32 values. For larger data or PII, use commitment patterns (hash/locator) instead.
Step 4: Batch multiple payments
Tempo Transactions allow you to batch multiple operations atomically. This is perfect for payroll, invoices, or settlements.
import { TempoTransactionRequest, Call } from 'tempo-alloy';
import { SolCall } from 'alloy/sol-types';
const recipient1 = address('0x70997970C51812dc3A010C7d01b50e0d17dc79C8');
const recipient2 = address('0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC');
const tokenAddress = address('0x20c0000000000000000000000000000000000001');
const calls: Call[] = [
{
to: tokenAddress,
input: ITIP20.transferCall({
to: recipient1,
amount: U256.from(100_000_000) // 100 USD
}).abi_encode(),
value: U256.ZERO
},
{
to: tokenAddress,
input: ITIP20.transferCall({
to: recipient2,
amount: U256.from(50_000_000) // 50 USD
}).abi_encode(),
value: U256.ZERO
}
];
const pending = await provider.send_transaction(
TempoTransactionRequest({ calls, ...Default.default() })
);
const txHash = pending.tx_hash();
console.log(`Batch payment sent! Hash: ${txHash}`);
Both transfers succeed or fail atomically.Batch transactions require the Tempo transaction format. Use the TypeScript SDK or build the transaction manually.
Understanding gas costs
Tempo’s gas costs are denominated in USD-stablecoins, not a volatile native token.
All costs are approximate and may vary based on network conditions.
| Operation | Typical Gas | Approx Cost (USD) |
|---|
| TIP-20 transfer (existing address) | 50,000 | $0.0001 |
| Transfer to new address | 300,000 | $0.0006 |
| First transaction from new account | 300,000 | $0.0006 |
| Batch payment (2 transfers) | ~120,000 | $0.0002 |
| Transfer with memo | ~55,000 | $0.00011 |
The costs are calculated based on:
- Base gas price targeting $0.0001 per 50,000 gas
- New state creation: 250,000 gas (TIP-1000)
- Account creation: 250,000 gas on first use
Next steps
Now that you’ve made your first transaction, explore more advanced features:
Use Tempo SDKs
Deep dive into TypeScript, Rust, Go, and Foundry SDKs
Learn TIP-20
Understand the TIP-20 token standard and its features
Smart accounts
Build with Tempo Transactions for fee sponsorship and batching
Deploy contracts
Deploy and interact with smart contracts on Tempo
Testnet tokens
The faucet provides these tokens:
| Token | Address | Symbol | Decimals |
|---|
| AlphaUSD | 0x20c0000000000000000000000000000000000001 | AUSD | 6 |
More testnet stablecoins will be added in the future.
Get help
Run into issues? Here’s how to get help:
Documentation
Browse comprehensive guides and references
GitHub Issues
Report bugs or request features
Block Explorer
Debug transactions and inspect state
RPC Reference
Full JSON-RPC API documentation